真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

android內(nèi)核剖析系列---JNI調(diào)用機(jī)制分析

為什么需要JNI?

成都創(chuàng)新互聯(lián)是一家專業(yè)提供大通企業(yè)網(wǎng)站建設(shè),專注與成都網(wǎng)站設(shè)計(jì)、做網(wǎng)站、H5高端網(wǎng)站建設(shè)、小程序制作等業(yè)務(wù)。10年已為大通眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)站建設(shè)公司優(yōu)惠進(jìn)行中。

android這個(gè)龐大的系統(tǒng)從下到上主要由linux內(nèi)核,C/C++庫(kù),java應(yīng)用程序框架,java應(yīng)用程序組成。這就涉及到一個(gè)問(wèn)題,C/C++庫(kù)如何與java應(yīng)用有交集,或者說(shuō)能相互調(diào)用,要解決這個(gè)問(wèn)題,就需要JNI登場(chǎng)了。


JNI調(diào)用機(jī)制分析

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

上文提到,JNI是為解決C和Java相互調(diào)用的問(wèn)題而誕生的。C和Java相互調(diào)用無(wú)非就是兩個(gè)方面,Java調(diào)用C和C調(diào)用Java。

Java調(diào)用C函數(shù)

如果你只定義了一個(gè)函數(shù),而將它的實(shí)現(xiàn)交給C,那么就將它定義為native類型好了。你或許會(huì)問(wèn)了,我用Java定義了一個(gè)函數(shù),但我卻沒(méi)用Java實(shí)現(xiàn)之,當(dāng)我調(diào)用這個(gè)函數(shù)的時(shí)候,Java編譯器不會(huì)報(bào)錯(cuò)嗎?答案是否定的,Java編譯器在遇到native類型的函數(shù)時(shí),不會(huì)關(guān)心該函數(shù)的具體實(shí)現(xiàn),相當(dāng)于native類型告訴Java編譯器,“喂,老兄,我實(shí)現(xiàn)了,只不過(guò)我不是用你的語(yǔ)言(Java)實(shí)現(xiàn)的,我是用別的語(yǔ)言(C)實(shí)現(xiàn)的”,所以編譯時(shí)Java編譯器不會(huì)報(bào)錯(cuò),只不過(guò)在調(diào)用native類型的函數(shù)前,程序員必須把C生成的動(dòng)態(tài)庫(kù)裝載進(jìn)內(nèi)存,否則程序會(huì)因?yàn)檎也坏较鄳?yīng)的native方法而出錯(cuò)。

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

規(guī)范:methodname_C = Packagename + methodname_Java。什么意思呢?在C中定義的函數(shù)名稱 = 包名 + 在Java中定義的函數(shù)名稱。還不明白?我們來(lái)舉個(gè)例子來(lái)看一下。

java:private nativefinal void init()

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

可以看到對(duì)應(yīng)的C函數(shù)多了兩個(gè)參數(shù),看起來(lái)莫名其妙,但這其實(shí)能讓C訪問(wèn)Java對(duì)象或函數(shù),JNIEnv對(duì)象是一個(gè)Java虛擬機(jī)所運(yùn)行的環(huán)境,jobject是調(diào)用該函數(shù)的對(duì)象。我們稍后會(huì)講到。

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

這是有必要的,這是為了區(qū)分開(kāi)不同包的兩個(gè)同名函數(shù),能夠讓Java編譯器找到正確的那個(gè)函數(shù)。事實(shí)上,Java調(diào)用native函數(shù)時(shí),編譯器會(huì)向native引擎?zhèn)鬟f調(diào)用者的包名,以及函數(shù)名稱,還有參數(shù)類型,以便可以根據(jù)這些信息找到正確的本地的那個(gè)函數(shù)。

C調(diào)用Java函數(shù)或者訪問(wèn)Java變量

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

1)獲取Java對(duì)象的類

jclass cls = env->GetObjectClass(jobject),還記得env和jobject嗎?沒(méi)錯(cuò),就是那兩個(gè)參數(shù)。現(xiàn)在知道那兩個(gè)參數(shù)的重要性了吧。不過(guò),這也意味著C調(diào)用Java函數(shù)只能在Java調(diào)用C函數(shù)體中進(jìn)行。

2)獲取Java函數(shù)的id值

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

3)找到了函數(shù)后,就可以調(diào)用該函數(shù)了

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



網(wǎng)站欄目:android內(nèi)核剖析系列---JNI調(diào)用機(jī)制分析
網(wǎng)頁(yè)路徑:http://weahome.cn/article/gcieii.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部