NDK動態(tài)注冊

動態(tài)注冊

在靜態(tài)注冊中,每次添加新函數(shù)后,要重新生成頭文件,而且函數(shù)名較長,操作起來非常麻煩,那使用動態(tài)注冊可以避免這些麻煩 。
而動態(tài)注冊可以避免這些麻煩。 JNI中提供了RegisterNatives方法來注冊函數(shù)
并且我們在調(diào)用 System.loadLibrary的時候,會在C/C++文件中回調(diào)一個名為 JNI_OnLoad 的函數(shù)
在這個函數(shù)中一般是做一些初始化設(shè)定和指定jni版本 我們可以在這個方法里面注冊函數(shù)
現(xiàn)在我們不需要頭文件,只需要 C/C++ 源文件,.mk文件也和靜態(tài)注冊的一樣

// jni頭文件   
#include <jni.h>  
   
#include <cassert>  
#include <cstdlib>  
#include <iostream>  
using namespace std;  
   
   
//native 方法實現(xiàn)  
jint get_random_num(){  
    return rand();  
}  
/*需要注冊的函數(shù)列表,放在JNINativeMethod 類型的數(shù)組中, 
以后如果需要增加函數(shù),只需在這里添加就行了 
參數(shù): 
1.java代碼中用native關(guān)鍵字聲明的函數(shù)名字符串 
2.簽名(傳進來參數(shù)類型和返回值類型的說明)  
3.C/C++中對應(yīng)函數(shù)的函數(shù)名(地址) 
*/  
static JNINativeMethod getMethods[] = {  
        {"getRandomNum","()I",(void*)get_random_num},  
};  
//此函數(shù)通過調(diào)用JNI中 RegisterNatives 方法來注冊我們的函數(shù)  
static int registerNativeMethods(JNIEnv* env, const char* className,JNINativeMethod* getMethods,int methodsNum){  
    jclass clazz;  
    //找到聲明native方法的類  
    clazz = env->FindClass(className);  
    if(clazz == NULL){  
        return JNI_FALSE;  
    }  
   //注冊函數(shù) 參數(shù):java類 所要注冊的函數(shù)數(shù)組 注冊函數(shù)的個數(shù)  
    if(env->RegisterNatives(clazz,getMethods,methodsNum) < 0){  
        return JNI_FALSE;  
    }  
    return JNI_TRUE;  
}  
   
static int registerNatives(JNIEnv* env){  
    //指定類的路徑,通過FindClass 方法來找到對應(yīng)的類  
    const char* className  = "com/example/wenzhe/myjni/JniTest";  
    return registerNativeMethods(env,className,getMethods, sizeof(getMethods)/ sizeof(getMethods[0]));  
}  
//回調(diào)函數(shù) 在這里面注冊函數(shù)  
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved){  
    JNIEnv* env = NULL;  
   //判斷虛擬機狀態(tài)是否有問題  
    if(vm->GetEnv((void**)&env,JNI_VERSION_1_6)!= JNI_OK){  
        return -1;  
    }  
    assert(env != NULL);  
    //開始注冊函數(shù) registerNatives -》registerNativeMethods -》env->RegisterNatives  
    if(!registerNatives(env)){  
        return -1;  
    }  
    //返回jni 的版本   
    return JNI_VERSION_1_6;  
}  

上面的代碼就能實現(xiàn)動態(tài)注冊jni了 以后要增加函數(shù)只需在java文件中聲明native方法,在C/C++文件中實現(xiàn),
并在getMethods數(shù)組添加一個元素并指明對應(yīng)關(guān)系,通過ndk-build 生成so庫就可以運行了
上面代碼中registerNatives()和 registerNativeMethods()方法是我們自己寫的,其實完全可以寫到一個函數(shù)里面
當(dāng)初不懂原理的時候看網(wǎng)上教程以為必須要這么寫,后來懶得改了,直接拿來用了, 而env->RegisterNatives()方法
是jni中提供的,用來注冊我們想要注冊的函數(shù)

參考文章

http://blog.csdn.net/wwj_748/article/details/52347341
http://blog.csdn.net/venusic/article/details/52121254
http://blog.csdn.net/u010925331/article/details/50992505 (很清楚)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,242評論 25 708
  • 在此特此聲明:一下所有鏈接均來自互聯(lián)網(wǎng),在此記錄下我的查閱學(xué)習(xí)歷程,感謝各位原創(chuàng)作者的無私奉獻 ! 技術(shù)一點一點積...
    遠航的移動開發(fā)歷程閱讀 11,214評論 12 197
  • 一、NDK產(chǎn)生的背景 Android平臺從誕生起,就已經(jīng)支持C、C++開發(fā)。眾所周知,Android的SDK基于J...
    Ten_Minutes閱讀 3,542評論 1 27
  • 寒冷的空氣中充滿快到新年的氣氛,只是待在這座城市的小小角落的我突然有些感慨。 七月,X先生離開的時候還是炎熱的夏天...
    RYUndo閱讀 168評論 0 0
  • 現(xiàn)實打敗烏托邦,生活都是眼前的茍且,毀了詩和遠方的田野。 黑色幽默,是一種荒誕的、變態(tài)的、病態(tài)的文學(xué)流派,把痛苦與...
    商業(yè)與觀察閱讀 322評論 0 0