中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

android內核剖析系列---JNI調用機制分析

發布時間:2020-07-21 02:10:41 來源:網絡 閱讀:419 作者:3542534801 欄目:移動開發

為什么需要JNI?

android這個龐大的系統從下到上主要由linux內核,C/C++庫,java應用程序框架,java應用程序組成。這就涉及到一個問題,C/C++庫如何與java應用有交集,或者說能相互調用,要解決這個問題,就需要JNI登場了。


JNI調用機制分析

JNI--java native interface,翻譯成中文是java本地接口,所謂的“本地”是指C/C++庫一層的C/C++語言(以下統稱C)。

上文提到,JNI是為解決C和Java相互調用的問題而誕生的。C和Java相互調用無非就是兩個方面,Java調用C和C調用Java。


Java調用C函數

如果你只定義了一個函數,而將它的實現交給C,那么就將它定義為native類型好了。你或許會問了,我用Java定義了一個函數,但我卻沒用Java實現之,當我調用這個函數的時候,Java編譯器不會報錯嗎?答案是否定的,Java編譯器在遇到native類型的函數時,不會關心該函數的具體實現,相當于native類型告訴Java編譯器,“喂,老兄,我實現了,只不過我不是用你的語言(Java)實現的,我是用別的語言(C)實現的”,所以編譯時Java編譯器不會報錯,只不過在調用native類型的函數前,程序員必須把C生成的動態庫裝載進內存,否則程序會因為找不到相應的native方法而出錯。

Java和C本不是同種語言,硬要讓它們能相互調用的話,我們就要遵循某種規范(就像ARM匯編和C相互調用時也要遵循某種規范一樣)。

規范:methodname_C = Packagename + methodname_Java。什么意思呢?在C中定義的函數名稱 = 包名 + 在Java中定義的函數名稱。還不明白?我們來舉個例子來看一下。

java:private native final void init()

C:static void android_content_AssetManager_init(JNIEnv *env,jobject clazz)

可以看到對應的C函數多了兩個參數,看起來莫名其妙,但這其實能讓C訪問Java對象或函數,JNIEnv對象是一個Java虛擬機所運行的環境,jobject是調用該函數的對象。我們稍后會講到。

為什么C中的函數要加上包名呢?這不是多此一舉嗎?

這是有必要的,這是為了區分開不同包的兩個同名函數,能夠讓Java編譯器找到正確的那個函數。事實上,Java調用native函數時,編譯器會向native引擎傳遞調用者的包名,以及函數名稱,還有參數類型,以便可以根據這些信息找到正確的本地的那個函數。


C調用Java函數或者訪問Java變量

正如Java調用C函數一樣,Java把類名、函數名稱和參數類型傳遞給native引擎,然后由native引擎處理(正確找到并調用)C函數。同理,C調用Java時,也需要把想要訪問的類名、函數名稱和參數傳遞給Java引擎。步驟如下:

1)獲取Java對象的類

jclass cls = env->GetObjectClass(jobject),還記得env和jobject嗎?沒錯,就是那兩個參數。現在知道那兩個參數的重要性了吧。不過,這也意味著C調用Java函數只能在Java調用C函數體中進行。

2)獲取Java函數的id值

jmethodId mid = env->GetMethodId(cls,"methodname","(Ljava/lang/String;)V"),前兩個參數不必說,第三個參數值得注意,它代表了Java函數的參數和返回值,參數在括號之中,返回值在括號之外。

3)找到了函數后,就可以調用該函數了

env->CallXXXMethod(jobject,mid,ret),其中XXX代表了返回值的類型,


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

永川市| 姚安县| 镇雄县| 屏南县| 武汉市| 五指山市| 手游| 聂拉木县| 柘城县| 郸城县| 湾仔区| 桃江县| 江城| 杭州市| 平原县| 南和县| 泰宁县| 马鞍山市| 雷州市| 濮阳县| 大英县| 河源市| 城口县| 枣阳市| 磐石市| 门源| 德惠市| 广平县| 敦煌市| 万盛区| 凌海市| 松原市| 夏河县| 九龙坡区| 松潘县| 余干县| 禹城市| 泰州市| 吴忠市| 文水县| 连平县|