JNIEnv
- 表示Java調(diào)用Native語言的環(huán)境璧尸,是一個封裝了幾乎全部JNI方法的指針
- 只在創(chuàng)建它的線程生效助赞,不能跨線程傳遞
- 不同線程的JNIEnv彼此獨立
- Native環(huán)境中創(chuàng)建的線程,如果需要訪問JNI非春,必須要調(diào)用AttachCurrentThread關(guān)聯(lián)柱徙,并使用DetachCurrentThread解除鏈接
JavaVM
- JavaVM是虛擬機(jī)在JNI層的代表
- 一個進(jìn)程只有一個JavaVM,所有線程共用一個JavaVM
- 在Java里奇昙,每個進(jìn)程可以產(chǎn)生多個JavaVM對象
- 但是在Android上护侮,每個進(jìn)程只有一個Dalvik虛擬機(jī)對象來服務(wù)所有Java和C/C++代碼
Java的dex字節(jié)碼和C/C++的.so同事運行Dalvik虛擬機(jī)之內(nèi),共同使用一個進(jìn)程空間敬矩。之所有能相互調(diào)用概行,也是因為有Dalvik虛擬機(jī)。
當(dāng)Java代碼需要C/C++代碼時弧岳,在Dalvik虛擬機(jī)加載進(jìn).so庫時,會先調(diào)用JNI_Onload()
业踏,此時會把JavaVM對象的指針存儲在C層Jni組件的全局環(huán)境中禽炬。
在Java層調(diào)用C層的本地函數(shù)時,調(diào)用C本地函數(shù)的線程必然通過Dalvik虛擬機(jī)來調(diào)用C層的本地函數(shù)勤家,此時腹尖,Dalvik虛擬機(jī)會為本地的C組件實例化一個JNIEnv指針,該指針指向Dalvik的具體函數(shù)列表伐脖,當(dāng)JNI的C組件調(diào)用Java層的方法或者屬性時热幔,需要通過JNIEnv指針來進(jìn)行調(diào)用。當(dāng)本地C/C++想獲得當(dāng)前線程所要使用的JNIEnv時讼庇,可以使用Dalvik虛擬機(jī)對象的JavaVM* jvm->GetEnv()
返回當(dāng)前線程所在的JNIEnv*绎巨。