細說JNI與NDK(四)動態(tài)和靜態(tài)注冊

細說JNI與NDK專題目錄:

細說JNI與NDK(一) 初體驗
細說JNI與NDK(二)基本操作)
細說JNI與NDK(三)ndk 配置說明
細說JNI與NDK(四)動態(tài)和靜態(tài)注冊
細說JNI與NDK(五)JNI 線程
細說JNI與NDK(六)靜態(tài)緩存儒将,異常捕獲椅您,內(nèi)置函數(shù)
細說JNI與NDK(七)Parcel底層JNI思想與OpenCV簡單對比

Android Framework源代碼中的動態(tài)注冊


2021-04-19 12.34.19.png

靜態(tài)注冊和動態(tài)注冊

靜態(tài)注冊

默認情況下邓深,就是靜態(tài)注冊肄鸽,靜態(tài)注冊是最簡單的方式,NDK開發(fā)過程中酝锅,基本上使用靜態(tài)注冊巧骚。前面的知識都是靜態(tài)注冊的方式吭产。

優(yōu)點: 開發(fā)簡單
缺點:

  1. JNI函數(shù)名非常長
  2. 捆綁 上層 包名 + 類名
  3. 運行期 才會去 匹配JNI函數(shù)个从,性能上 低于 動態(tài)注冊

動態(tài)注冊

再看Android Framework源代碼的Native層拦宣,Android 系統(tǒng)的C++源碼:基本上都是動態(tài)注冊。

動態(tài)注冊是怎么玩轉(zhuǎn)的信姓?

明白一個簡單的道理鸵隧,Java中我們new 類,默認會調(diào)用構(gòu)造函數(shù)意推,重寫了構(gòu)造函數(shù)豆瘫,就會調(diào)用我們自己的。NDK中Jni函數(shù)也是這樣菊值,默認會有JNI_OnLoad 一系列函數(shù)外驱,我們重寫JNI_OnLoad來加載我們自己的邏輯。

當我們調(diào)用腻窒,System.loadLiberary("xxxxx");
<---->
實際上自動調(diào)用了JNI_OnLoad 做動態(tài)注冊

先看下示例代碼
? Java 部分


public native void dynamicJavaM01();
public native int dynamicJavaM01(String value);
調(diào)用
case R.id.jni_regist_1:
                dynamicJavaM01();
                break;
 case R.id.jni_regist_2:
                dynamicJavaM01("JNI動態(tài)注冊昵宇,JNI傳參");
                break;

? C++ 部分


#include "include/common_head.h"
//JNIEnv *env, jobject thiz,  默認這兩個參數(shù)是可以省略,如果不用的話
//void dynamicM01(JNIEnv *env, jobject thiz)
void dynamicM01() {
    LOGD("我是動態(tài)注冊的函數(shù) dynamicM01...");
}

int dynamicM02(JNIEnv *env, jobject thiz, jstring value) {
    const char * text = env->GetStringUTFChars(value, nullptr);
    LOGD("我是動態(tài)注冊的函數(shù) dynamicM02...%s",text);
    env->ReleaseStringUTFChars(value,text);
    return 200;
}

JavaVM *javaVm;
const char *class_name = "top/zcwfeng/jni/JavaJNIActivity";
//name,signature,*
static const JNINativeMethod methods[] = {
        {"dynamicJavaM01", "()V",                   (void *) (dynamicM01)},
        {"dynamicJavaM02", "(Ljava/lang/String;)I", (int *) (dynamicM02)},
};

jint JNI_OnLoad(JavaVM *vm, void *unused) {
    ::javaVm = vm;
    JNIEnv *jniEnv = nullptr;
    int result = javaVm->GetEnv(reinterpret_cast<void **>(&jniEnv), JNI_VERSION_1_6);
    //result 等與0 成功儿子,默認不成文規(guī)則瓦哎,封裝庫都是成功就是0【如ffmpeg庫等】
    if (result != JNI_OK) {
        return -1;
    }
    LOGE("System.loadLibrary --->JNI Load init success");

    jclass clazz = jniEnv->FindClass(class_name);

    //RegisterNatives(jclass clazz, const JNINativeMethod* methods,jint nMethods)
    jniEnv->RegisterNatives(clazz, methods,sizeof(methods)/sizeof(JNINativeMethod));

    LOGE("動態(tài) 注冊 dynamic success");
    return JNI_VERSION_1_6;// AS的JDK在JNI默認最高1.6  Java的JDKJNI 1.8
}

  • JNI_OnLoad 中賦值我們用了域的方式,如:this.a = a ---> ::javaVm = vm
  • 默認不成文規(guī)則柔逼,C 中封裝庫都是成功就是0
  • AS的JDK目前JNI默認最高1.6 和 Java的JDK的JNI 1.8不同
  • JNI_OK 就是JNI提供的一些宏定義方便使用蒋譬。
  • 動態(tài)注冊的方法參數(shù),JNIEnv *env 和 jobject thiz愉适,如果沒有用到是可以不放到參數(shù)列表中犯助,沒有影像。
  • 動態(tài)注冊核心RegisterNatives

① 重寫JNI_OnLoad
② JavaVM 初始化獲取JNIEnv维咸,并獲取到j(luò)class
③ 注冊函數(shù)

//RegisterNatives(jclass clazz, const JNINativeMethod* methods,jint nMethods)
    jniEnv->RegisterNatives(clazz, methods,sizeof(methods)/sizeof(JNINativeMethod));

參數(shù)需要提供剂买,所在的類,數(shù)組(包含需要動態(tài)注冊的方法)癌蓖,數(shù)組的大小
小技巧瞬哼,傳入JNINativeMethod* 以為指針相當于我們定義一個數(shù)組

如何選擇看個人喜好和代碼的設(shè)計
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請通過簡信或評論聯(lián)系作者费坊。
  • 序言:七十年代末倒槐,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子附井,更是在濱河造成了極大的恐慌讨越,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,718評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件永毅,死亡現(xiàn)場離奇詭異把跨,居然都是意外死亡,警方通過查閱死者的電腦和手機沼死,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評論 3 385
  • 文/潘曉璐 我一進店門着逐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事耸别〗“牛” “怎么了?”我有些...
    開封第一講書人閱讀 158,207評論 0 348
  • 文/不壞的土叔 我叫張陵秀姐,是天一觀的道長慈迈。 經(jīng)常有香客問我,道長省有,這世上最難降的妖魔是什么痒留? 我笑而不...
    開封第一講書人閱讀 56,755評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮蠢沿,結(jié)果婚禮上伸头,老公的妹妹穿的比我還像新娘。我一直安慰自己舷蟀,他們只是感情好恤磷,可當我...
    茶點故事閱讀 65,862評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著雪侥,像睡著了一般碗殷。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上速缨,一...
    開封第一講書人閱讀 50,050評論 1 291
  • 那天锌妻,我揣著相機與錄音,去河邊找鬼旬牲。 笑死仿粹,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的原茅。 我是一名探鬼主播吭历,決...
    沈念sama閱讀 39,136評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼擂橘!你這毒婦竟也來了晌区?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,882評論 0 268
  • 序言:老撾萬榮一對情侶失蹤通贞,失蹤者是張志新(化名)和其女友劉穎朗若,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體昌罩,經(jīng)...
    沈念sama閱讀 44,330評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡哭懈,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,651評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了茎用。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片遣总。...
    茶點故事閱讀 38,789評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡睬罗,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出旭斥,到底是詐尸還是另有隱情容达,我是刑警寧澤,帶...
    沈念sama閱讀 34,477評論 4 333
  • 正文 年R本政府宣布琉预,位于F島的核電站董饰,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏圆米。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,135評論 3 317
  • 文/蒙蒙 一啄栓、第九天 我趴在偏房一處隱蔽的房頂上張望娄帖。 院中可真熱鬧,春花似錦昙楚、人聲如沸近速。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽削葱。三九已至,卻和暖如春淳梦,著一層夾襖步出監(jiān)牢的瞬間析砸,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評論 1 267
  • 我被黑心中介騙來泰國打工爆袍, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留首繁,地道東北人。 一個月前我還...
    沈念sama閱讀 46,598評論 2 362
  • 正文 我出身青樓陨囊,卻偏偏與公主長得像弦疮,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子蜘醋,可洞房花燭夜當晚...
    茶點故事閱讀 43,697評論 2 351

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