日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android JNI_OnLoad()函数

發(fā)布時(shí)間:2024/4/15 Android 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android JNI_OnLoad()函数 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

JVM加載完本地庫會調(diào)用JNI_OnLoad()函數(shù)


當(dāng)Android的 VM(VirtualMachine)執(zhí)行到C組件(即*so文件)里的System.loadLibrary()函數(shù)時(shí),首先會去執(zhí)行C組件里的JNI_OnLoad()函數(shù)。它的用途有二:

1.?????? 告訴VM此C組件使用那一個JNI版本。如果你的*.so文件沒有提供JNI_OnLoad()函數(shù),VM會默認(rèn)該*.so檔是使用最老的JNI 1.1版本。由于新版的JNI做了許多擴(kuò)充,如果需要使用JNI的新版功能,例如JNI 1.4的 java.nio.ByteBuffer, 就必須藉由JNI_OnLoad()函數(shù)來告知VM。

2.?????? 由于VM執(zhí)行到System.loadLibrary()函數(shù)時(shí),就會立即先呼叫JNI_OnLoad(),所以C組件的開發(fā)者可以藉由JNI_OnLoad()來進(jìn)行C組件內(nèi)的初期值之設(shè)定(Initialization)。

?

例如,在Android的/system/lib/libmedia_jni.so檔案里,就提供了JNI_OnLoad()函數(shù),其程序代碼片段為:

?

//#define?LOG_NDEBUG?0

#define?LOG_TAG?"MediaPlayer-JNI"

………

jint?JNI_OnLoad(JavaVM*?vm,?void*?reserved)

{

????JNIEnv*?env?=?NULL;

????jint?result?=?-1;

?

????if?(vm->GetEnv((void**)?&env,?JNI_VERSION_1_4)?!=?JNI_OK)?{

????????LOGE("ERROR:?GetEnv?failed\n");

????????goto?bail;

????}

????assert(env?!=?NULL);

????if?(register_android_media_MediaPlayer(env)?<?0)?{

????????LOGE("ERROR:?MediaPlayer?native?registration?failed\n");

????????goto?bail;

????}

????if?(register_android_media_MediaRecorder(env)?<?0)?{

????????LOGE("ERROR:?MediaRecorder?native?registration?failed\n");

????????goto?bail;

????}

????if?(register_android_media_MediaScanner(env)?<?0)?{

????????LOGE("ERROR:?MediaScanner?native?registration?failed\n");

????????goto?bail;

????}

????if?(register_android_media_MediaMetadataRetriever(env)?<?0)?{

????????LOGE("ERROR:?MediaMetadataRetriever?native?registration?failed\n");

????????goto?bail;

????}

????/*?success?--?return?valid?version?number?*/

????result?=?JNI_VERSION_1_4;

bail:

????return?result;

}

//?KTHXBYE

?

??? 此函數(shù)回傳JNI_VERSION_1_4值給VM,于是VM知道了其所使用的JNI版本了。此外,它也做了一些初期的動作(可呼叫任何本地函數(shù)),例如指令:

?

???if?(register_android_media_MediaPlayer(env)?<?0)?{

????????LOGE("ERROR:?MediaPlayer?native?registration?failed\n");

????????goto?bail;

????}

?

就將此組件提供的各個本地函數(shù)(NativeFunction)登記到VM里,以便能加快后續(xù)呼叫本地函數(shù)之效率。

??? JNI_OnUnload()函數(shù)與JNI_OnLoad()相對應(yīng)的。在加載C組件時(shí)會立即呼叫JNI_OnLoad()來進(jìn)行組件內(nèi)的初期動作;而當(dāng)VM釋放該C組件時(shí),則會呼叫JNI_OnUnload()函數(shù)來進(jìn)行善后清除動作。當(dāng)VM呼叫JNI_OnLoad()或JNI_Unload()函數(shù)時(shí),都會將VM的指標(biāo)(Pointer)傳遞給它們,其參數(shù)如下:

?

jint?JNI_OnLoad(JavaVM*?vm,?void*?reserved)

{

????? ………

}

?

jint?JNI_OnUnload(JavaVM*?vm,?void*?reserved)

{

????? ………

}

?

在JNI_OnLoad()函數(shù)里,就透過VM之指標(biāo)而取得JNIEnv之指標(biāo)值,并存入env指針變量里,如下述指令:

?

jint?JNI_OnLoad(JavaVM*?vm,?void*?reserved)

{

????JNIEnv*?env?=?NULL;

????jint?result?=?-1;

?

????if?(vm->GetEnv((void**)?&env,?JNI_VERSION_1_4)?!=?JNI_OK)?{

????????LOGE("ERROR:?GetEnv?failed\n");

????????goto?bail;

????}

?

???由于VM通常是多執(zhí)行緒(Multi-threading)的執(zhí)行環(huán)境。每一個執(zhí)行緒在呼叫JNI_OnLoad()時(shí),所傳遞進(jìn)來的JNIEnv指標(biāo)值都是不同的。為了配合這種多執(zhí)行緒的環(huán)境,C組件開發(fā)者在撰寫本地函數(shù)時(shí),可藉由JNIEnv指標(biāo)值之不同而避免執(zhí)行緒的數(shù)據(jù)沖突問題,才能確保所寫的本地函數(shù)能安全地在Android的多執(zhí)行緒VM 里安全地執(zhí)行。基于這個理由,當(dāng)在呼叫C組件的函數(shù)時(shí),都會將JNIEnv指標(biāo)值傳遞給它,如下:

jint?JNI_OnLoad(JavaVM*?vm,?void*?reserved)

{

JNIEnv*?env?=?NULL;

? ……….

????if?(register_android_media_MediaPlayer(env)?<?0)?{

???????…….

????}

???? }

這JNI_OnLoad()呼叫register_android_media_MediaPlayer(env)函數(shù)時(shí),就將env指標(biāo)值傳遞過去。如此,在register_android_media_MediaPlayer()函數(shù)就能藉由該指標(biāo)值而區(qū)別不同的執(zhí)行緒,以便化解數(shù)據(jù)沖突的問題。

????? 例如,在register_android_media_MediaPlayer()函數(shù)里,可撰寫下述指令:

???????if ((*env)->MonitorEnter(env, obj) != JNI_OK) {

????????????………

?}

?

? ??查看是否已經(jīng)有其它執(zhí)行緒進(jìn)入此對象,如果沒有,此執(zhí)行緒就進(jìn)入該對象里執(zhí)行了。還有,也可撰寫下述指令:

?

????????if ((*env)->MonitorExit(env, obj) != JNI_OK) {

?????????????………

?????????}

?

查看是否此執(zhí)行緒正在此對象內(nèi)執(zhí)行,如果是,此執(zhí)行緒就會立即離開。

與50位技術(shù)專家面對面20年技術(shù)見證,附贈技術(shù)全景圖

總結(jié)

以上是生活随笔為你收集整理的Android JNI_OnLoad()函数的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。