標籤:
摘要: 摘要: 轉載請聲明:原文轉自:http://www.cnblogs.com/xiezie/p/5930032.html
從C/C++層調用JAVA層代碼步驟:1. 在JAVA類中建立java方法和本地方法
public class TestNdk{ int a;//本樣本中將被修改的JAVA變數 Handler handler; public TestNdk(Handler handler){ this.handler = handler; setUp(); } public native void setUp();//本地方法 public native static int getStringFromNative();//本地方法 public int getA() { return a; } public native void setA(int a);//本地方法 public void notifyFiledChange(){//本樣本中將被C/C++調用的JAVA方法 Message message = new Message(); Bundle bundle = new Bundle(); bundle.putInt("a",a); message.setData(bundle); message.what=1; handler.sendMessage(message); } static { System.loadLibrary("MyJni");//匯入產生的連結庫檔案 }}
2.在JNI檔案夾下建立類對應的.h檔案(可通過JAVAH命令產生該類的.h檔案,就不贅述了),建立.cpp檔案(用於編寫C/C++層的代碼)
/* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h>/* Header for class com_x_mp4player_TestNdk */#ifndef _Included_com_x_mp4player_TestNdk#define _Included_com_x_mp4player_TestNdk#ifdef __cplusplusextern "C" {#endif/* * Class: com_x_mp4player_TestNdk * Method: setUp * Signature: ()V */JNIEXPORT void JNICALL Java_com_x_mp4player_TestNdk_setUp (JNIEnv *, jobject);/* * Class: com_x_mp4player_TestNdk * Method: setA * Signature: (I)V */JNIEXPORT void JNICALL Java_com_x_mp4player_TestNdk_setA (JNIEnv *env, jobject thiz,jint i);/* * Class: com_x_mp4player_TestNdk * Method: getStringFromNative * Signature: ()I */JNIEXPORT jint JNICALL Java_com_x_mp4player_TestNdk_getStringFromNative (JNIEnv *, jclass);#ifdef __cplusplus}#endif#endif
#include <jni.h>#include <com_x_mp4player_TestNdk.h>jobject m_object;jmethodID m_mid;jfieldID m_fid;JNIEXPORT jint JNICALL Java_com_x_mp4player_TestNdk_getStringFromNative (JNIEnv *env, jclass cls) { return 1;}JNIEXPORT void JNICALL Java_com_x_mp4player_TestNdk_setUp (JNIEnv *env, jobject thiz) { jclass clazz = (*env).GetObjectClass(thiz);//擷取該對象的類 m_object = (*env).NewGlobalRef(thiz);//建立對象的本地變數 m_mid =(*env).GetMethodID(clazz, "notifyFiledChange", "()V");//擷取JAVA方法的ID m_fid = (*env).GetFieldID(clazz,"a","I");//擷取java變數的ID return;}JNIEXPORT void JNICALL Java_com_x_mp4player_TestNdk_setA (JNIEnv *env, jobject thiz,jint i) { (*env).SetIntField( m_object, m_fid,i); (*env).CallVoidMethod(m_object,m_mid); return;}
3.調用JAVA方法需要類的對象
在C/C++層擷取類的對象的方法有兩種:
JNIEXPORT void JNICALL Java_com_x_mp4player_TestNdk_setUp (JNIEnv *env, jobject thiz) {
... jclass clazz = (*env).GetObjectClass(thiz);//擷取該對象的類 ... return;}
方法如下:
1.通過JAVA層的本地方法建立同類對象
步驟:
I.通過對象擷取類
II.通過類擷取類的構造方法的ID
III.基於方法ID和類,建立新對象
JNIEXPORT void JNICALL JAVA_nativeMethod (JNIEnv *env, jobject thiz,jint i){ ... jclass clazz = (*env).GetObjectClass(thiz); jmethodID mid = (*env).GetMethodID(clazz,"<init>","()V"); jobject obj = (*env).NewObject(clazz,mid); ... return;}
2.通過C/C++建立不同類對象
步驟:
I.通過FindClass方法擷取需要的類
II.通過類擷取類的構造方法的ID
III.基於方法ID和類,建立新對象
JNIEXPORT void JNICALL JAVA_nativeMethod (JNIEnv *env, jobject thiz,jint i){ ... jclass clazz = (*env).FindClass("com/x/test/Test");//參數為類路徑 jmethodID mid = (*env).GetMethodID(clazz,"<init>","()V"); jobject obj = (*env).NewObject(clazz,mid); ... return;}
4.調用java方法的步驟:
-
- 擷取類的方法ID
- 基於對象和方法id調用JAVA方法
- 樣本中是java調用本地方法setUp後,調用本地方法setA(int i),在本地方法setA(int i)中調用JAVA方法notifyFiledChange()方法
5.C/C++直接存取JAVA變數
-
- 擷取對象的變數的ID
- 基於對象和變數id存取變數
Android JNI之C/C++層調用JAVA