日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > Android >内容正文

Android

03_Android NDK中C语言调用Java代码,javah的使用,javap的使用以及生成签名,Android.mk的编写,C代码的编写

發(fā)布時(shí)間:2024/9/27 Android 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 03_Android NDK中C语言调用Java代码,javah的使用,javap的使用以及生成签名,Android.mk的编写,C代码的编写 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.


1? 案例場景,通過C語言回調(diào)Java的代碼,案例的最終界面:

2? 案例的代碼結(jié)構(gòu)如下:

3 編寫DataProvider的代碼:

package com.example.ndkcallback;

?

public class DataProvider {

??? //C調(diào)用java空方法

??? public void helloFromJava(){

?????? System.out.println("哈哈哈? 我被調(diào)用了");

??? }

??? //C調(diào)用java中的帶兩個(gè)int參數(shù)的方法

??? public int Add(int x,int y){

?????? int result=x+y;

?????? System.out.println("result:"+result);

?????? return result;

??? }

??? //C調(diào)用java中參數(shù)為string的方法

??? public void printString(String s) {

?????? System.out.println(s);

??? }

???

??? public static void demo(){

?????? System.out.println("哈哈哈,我是靜態(tài)方法");

??? }

???

??? public native void callMethod1();

??? public native void callMethod2();

??? public native void callMethod3();

??? public native void callMethod4();

??? public native void callMethod5();

}

4 通過DataProvider獲得頭文件

接著帶有header的結(jié)構(gòu)如下:

5 編寫MainActivity代碼:

package com.example.ndkcallback;

?

import android.os.Bundle;

import android.support.v7.app.ActionBarActivity;

import android.view.View;

?

public class MainActivity extends ActionBarActivity {

?

???????? DataProvider dp;

????????

???????? static {

?????????????????? System.loadLibrary("hello");

???????? }

????????

???????? public void helloFromJava() {

?????????????????? System.out.print("哈哈哈,我被調(diào)用了");

???????? }

????????

???????? @Override

???????? protected void onCreate(Bundle savedInstanceState) {

?????????????????? super.onCreate(savedInstanceState);

?????????????????? setContentView(R.layout.activity_main);

?????????????????? dp = new DataProvider();

???????? }

????????

???????? public void click1(View view){

?????????????????? dp.callMethod1();???

???????? }

????????

???????? public void click2(View view){

?????????????????? dp.callMethod2();

???????? }

????????

???????? public void click3(View view){

?????????????????? dp.callMethod3();

???????? }

????????

???????? public void click4(View view){

?????????????????? dp.callMethod4();

???????? }

????????

???????? public void click5(View view){

?????????????????? dp.callMethod5();

???????? }

}

6 編寫布局文件activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

??? xmlns:tools="http://schemas.android.com/tools"

??? android:layout_width="match_parent"

??? android:layout_height="match_parent"

??? tools:context=".MainActivity" >

?

??? <Button

??????? android:onClick="click1"

??????? android:id="@+id/button1"

??????? android:layout_width="wrap_content"

??????? android:layout_height="wrap_content"

??????? android:layout_alignParentLeft="true"

??????? android:layout_alignParentTop="true"

??????? android:text="回調(diào)javahelloFromJava" />

?

??? <Button

???????? android:onClick="click2"

??????? android:id="@+id/button2"

??????? android:layout_width="wrap_content"

??????? android:layout_height="wrap_content"

??????? android:layout_alignParentLeft="true"

??????? android:layout_below="@+id/button1"

??????? android:text="回調(diào)javaAdd" />

?

??? <Button

??????? android:onClick="click3"

??????? android:id="@+id/button3"

??????? android:layout_width="wrap_content"

??????? android:layout_height="wrap_content"

??????? android:layout_alignParentLeft="true"

??????? android:layout_below="@+id/button2"

??????? android:text="回調(diào)javaPrintString" />

?

??? <Button

???????? android:onClick="click4"

??????? android:id="@+id/button4"

??????? android:layout_width="wrap_content"

??????? android:layout_height="wrap_content"

??????? android:layout_alignParentLeft="true"

??????? android:layout_below="@+id/button3"

??????? android:text="回調(diào)java中其它類的方法" />

?

??? <Button

??????? android:onClick="click5"

??????? android:id="@+id/button5"

??????? android:layout_width="wrap_content"

??????? android:layout_height="wrap_content"

??????? android:layout_alignParentLeft="true"

??????? android:layout_below="@+id/button4"

??????? android:text="回調(diào)java中靜態(tài)的方法" />

?

</RelativeLayout>

7 接下來,通過javap命令獲得DataProvider的方法簽名,在cygwin上進(jìn)入/NdkCallBack/bin/classes.

命令如下:

toto@toto-PC /cygdrive/e/workspace/Android/NdkCallBack/bin/classes

$ javap -scom.example.ndkcallback.DataProvider

上面紅框圈的分別是執(zhí)行命令和方法簽名。這個(gè)簽名在hello.c中會(huì)用到。

7 接下來編寫hello.c

#include "com_example_ndkcallback_DataProvider.h"

?

/**

?* 調(diào)用:DataProvider中的 public void helloFromJava();

?*/

JNIEXPORT void JNICALL Java_com_example_ndkcallback_DataProvider_callMethod1

? (JNIEnv *env, jobject jobject) {

??? /**

???? * Class<?> forName = Class.forName("com.example.ndkcallback.DataProvider");

???? * Method declaredMethod = forName.getDeclaredMethod("helloFromJava", new Class[]{});

???? * declaredMethod.invoke(forName.newInstance(), new Object[]{});

???? */

???????? //jclass????? (*FindClass)(JNIEnv*, const char*);

??? jclass clazz = (*env)->FindClass(env,"com/example/ndkcallback/DataProvider");

??? //jmethodID (*GetMethodID)(JNIEnv*,jclass,const char*,const char*)

??? //方法簽名?? 參數(shù)和返回值

??? //GetMethodID中參數(shù)分別是env指針,class,方法名,方法簽名

??? jmethodID methodId=(*env)->GetMethodID(env,clazz,"helloFromJava","()V");

??? //通過 void??????? (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);來調(diào)用Java的代碼

??? (*env)->CallVoidMethod(env,jobject,methodId);

}

?

/**

?* 調(diào)用:DataProvider中的 public int Add(int, int);

?*/

JNIEXPORT void JNICALL Java_com_example_ndkcallback_DataProvider_callMethod2

? (JNIEnv *env, jobject jobject) {

???????? jclass clazz=(*env)->FindClass(env,"com/example/ndkcallback/DataProvider");

???????? //這里的方法簽名中有幾個(gè)I表示有幾個(gè)參數(shù)

???????? jmethodID methodId=(*env)->GetMethodID(env,clazz,"Add","(II)I");

???????? // jint??????? (*CallIntMethod)(JNIEnv*, jobject, jmethodID, ...);

???????? (*env)->CallIntMethod(env,jobject,methodId,3,5);

}

?

/**

?* 調(diào)用:DataProvider中的 public void printString(java.lang.String);

?*/

JNIEXPORT void JNICALL Java_com_example_ndkcallback_DataProvider_callMethod3

? (JNIEnv *env, jobject jobject) { // 參數(shù) object? 就是native方法所在的類

???????? jclass clazz=(*env)->FindClass(env,"com/example/ndkcallback/DataProvider");

???????? jmethodID methodId=(*env)->GetMethodID(env,clazz,"printString","(Ljava/lang/String;)V");

???????? // jint??????? (*CallIntMethod)(JNIEnv*, jobject, jmethodID, ...);

???????? jstring str=(*env)->NewStringUTF(env,"hello");

?

???????? (*env)->CallVoidMethod(env,jobject,methodId,str);

}

?

JNIEXPORT void JNICALL Java_com_example_ndkcallback_DataProvider_callMethod4

? (JNIEnv * env, jobject j){

???????? jclass clazz=(*env)->FindClass(env,"com/example/ndkcallback/MainActivity");

???????? //? jmethodID?? (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);

???????? // 方法簽名? 參數(shù)和返回值

???????? jmethodID methodId=(*env)->GetMethodID(env,clazz,"helloFromJava","()V");

???????? // void??????? (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);

???????? // 需要?jiǎng)?chuàng)建DataProvider 對(duì)象

???????? // jobject???? (*AllocObject)(JNIEnv*, jclass);

???????? jobject obj=(*env)->AllocObject(env,clazz);? // new MainActivity();

???????? (*env)->CallVoidMethod(env,obj,methodId);

?

}

?

JNIEXPORT void JNICALL Java_com_example_ndkcallback_DataProvider_callMethod5

? (JNIEnv * env, jobject j){

???????? jclass clazz=(*env)->FindClass(env,"com/example/ndkcallback/DataProvider");

???????? //???? jmethodID?? (*GetStaticMethodID)(JNIEnv*, jclass, const char*, const char*);

???????? ?jmethodID? methodid=(*env)->GetStaticMethodID(env,clazz,"demo","()V");

???????? //void??????? (*CallStaticVoidMethod)(JNIEnv*, jclass, jmethodID, ...);

???????? ?(*env)->CallStaticVoidMethod(env,clazz,methodid);

}

8 編寫Android.mk文件,內(nèi)容如下:

LOCAL_PATH := $(call my-dir)

?

include $(CLEAR_VARS)

?

LOCAL_MODULE??? := libhello

LOCAL_SRC_FILES := Hello.c

?

include $(BUILD_SHARED_LIBRARY)

9 編寫Android的清單文件,內(nèi)容如下:

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

??? package="com.example.ndkcallback"

??? android:versionCode="1"

??? android:versionName="1.0" >

?

??? <uses-sdk

??????? android:minSdkVersion="8"

??????? android:targetSdkVersion="19" />

?

??? <application

??????? android:allowBackup="true"

??????? android:icon="@drawable/ic_launcher"

??????? android:label="@string/app_name"

??????? android:theme="@style/AppTheme" >

??????? <activity

??????????? android:name="com.example.ndkcallback.MainActivity"

??????????? android:label="@string/app_name" >

??????????? <intent-filter>

??????????????? <action android:name="android.intent.action.MAIN" />

?

??????????????? <category android:name="android.intent.category.LAUNCHER" />

??????????? </intent-filter>

??????? </activity>

??? </application>

?

</manifest>

10 交叉編譯,生成.so文件

成功之后,查看Android控制臺(tái)打印的結(jié)果

?

?

總結(jié)

以上是生活随笔為你收集整理的03_Android NDK中C语言调用Java代码,javah的使用,javap的使用以及生成签名,Android.mk的编写,C代码的编写的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。