Android JNI之C/C++層調用JAVA

 轉載請聲明:原文轉自:http://www.cnblogs.com/xiezie/p/5930032.html 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++層的代碼)

  •   .h文件:
/* 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 __cplusplus extern "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
  •   .cpp文件
#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++層獲取類的對象的方法有兩種:java

  • 經過JAVA層調用本地方法(如示例中的setUp()方法),在調用時,會傳入對象jobject或者對象的類jclassthis

JNIEXPORT void JNICALL Java_com_x_mp4player_TestNdk_setUp
        (JNIEnv *env, jobject thiz) {
... jclass clazz = (*env).GetObjectClass(thiz);//獲取該對象的類 ... return; }
  • 經過C/C++建立java對象spa

方法以下:3d

1.經過JAVA層的本地方法建立同類對象code

步驟:htm

I.經過對象獲取類對象

II.經過類獲取類的構造方法的IDblog

III.基於方法ID和類,建立新對象get

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;
}

 3.經過C++直接建立

 

4.調用java方法的步驟:

    1. 獲取類的方法ID
    2. 基於對象和方法id調用JAVA方法

  • 示例中是java調用本地方法setUp後,調用本地方法setA(int i),在本地方法setA(int i)中調用JAVA方法notifyFiledChange()方法

 

5.C/C++直接存取JAVA變量

    1. 獲取對象的變量的ID
    2. 基於對象和變量id存取變量

相關文章
相關標籤/搜索