NDK動態註冊

關於NDK想必大家都瞭解一點如

靜態註冊

    //動態註冊
    public native void registerJava01(String text);

這是一個最基本的Native函數
那麼我們之前採用的靜態註冊就是在c/c++文件中填寫

extern "C"
JNIEXPORT void JNICALL
Java_com_example_myndk_MainActivity_registerJava01(){}

那麼這就是一種靜態註冊,也就是名字是組合得來的,但是當我們看有些源碼的時候我們發現並不是這樣的,其實他們就採用了靜態註冊的方法來註冊的。

動態註冊

所謂的動態註冊就是不需要一個方法名一個方法名的形式去寫,只需要寫一個就行,開始吧:
動態註冊需要實現這個方法

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM * javaVm,void * pVoid){}

怎麼理解這個方法呢,可以想成Aactivity中的onCreate這個方法,當MainActivity一加載的時候,就會調用這個方法。

//虛擬機

JavaVM * jvm;
void register01(JNIEnv *env,jobject instance,jstring text)
{
    const char* textValue = env->GetStringUTFChars(text,NULL);
    __android_log_print(ANDROID_LOG_DEBUG,"hongbiao","動態註冊的函數:%s",textValue);
    env->ReleaseStringUTFChars(text,textValue);
}
//因爲註冊的那個方法需要這個結構體,所以需要創建
/**
 * typedef struct {
    const char* name; 對應java中的方法名
    const char* signature; 編碼描述
    void*       fnPtr;可以理解爲接受的函數,數據將會傳到這個函數裏面來
} JNINativeMethod;
 */
RegisterNatives static  const JNINativeMethod jniNativeMethod[] =
 {
 //這是一個數組,將需要進行動態註冊方法放到這裏面來
 {"registerJava01","(Ljava/lang/String;)V",(void *)(register01)}
};
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM * javaVm,void * pVoid){
    ::jvm = javaVm;
    JNIEnv* jniEnv = nullptr;
    //通過虛擬機,創建全新的evn
    jint result = javaVm->GetEnv(reinterpret_cast<void **>(&jniEnv), 			  			
    		JNI_VERSION_1_6);
    if(result!=JNI_OK){
        return -1;
    }
    const char * mainActivityClassStr = "com/example/myndk/MainActivity";
    jclass mainActivity = jniEnv->FindClass(mainActivityClassStr);
    //在哪裏動態註冊
    jniEnv->RegisterNatives(mainActivity,
    						jniNativeMethod,
    						//下面兩個主要是進行個數的計算 		
    				sizeof(jniNativeMethod)/ sizeof(JNINativeMethod));
    return JNI_VERSION_1_6;
}

其實動態註冊就是上面描述的這樣

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章