在native執行緒利用JNI 反射自定義類--ndk開發參考2
阿新 • • 發佈:2019-02-03
從前面我們知道,在虛擬機器初始化後,執行Java程式碼的方法時,要先查詢到類,也就是呼叫函式FindClass。接著後面分析怎麼樣從dex檔案載入類資料到記憶體,現在開始對查詢函式FindClass進行分析,就很好理解了,因為前面介紹載入類到記憶體的流程已經很清楚。函式FindClass程式碼如下:
static jclass FindClass(JNIEnv* env, const char* name)
{
這個函式傳入兩個引數,第一個引數是jni的環境引數;第二個引數name是需要查詢的類描述名稱。
JNI_ENTER();
const Method* thisMethod;
ClassObject* clazz;
jclass jclazz = NULL;
Object* loader;
char* descriptor = NULL;
thisMethod = dvmGetCurrentJNIMethod();
assert(thisMethod != NULL);
這段程式碼是獲取當前正在執行的JNI載入方法。
descriptor = dvmNameToDescriptor(name);
if (descriptor == NULL) {
clazz = NULL;
goto bail;
}
這段程式碼是把查詢類的名稱轉換類描述的方式,以便從類索引表裡查詢到。
//Thread* self = dvmThreadSelf();
if (_self->classLoaderOverride != NULL) {
/* hack for JNI_OnLoad */
assert(strcmp(thisMethod->name, "nativeLoad") == 0);
loader = _self->classLoaderOverride;
這段程式碼是使用本執行緒過載載入方法,也就是使用 nativeLoad的本地方法。
} else if (thisMethod == gDvm.methFakeNativeEntry) {
/* start point of invocation interface */
if (!gDvm.initializing)
loader = dvmGetSystemClassLoader();
else
loader = NULL;
這段程式碼是使用系統裡的類載入器。
} else {
loader = thisMethod->clazz->classLoader;
這行程式碼是使用本類裡的載入器。
}
clazz = dvmFindClassNoInit(descriptor, loader);
這行程式碼是使用指定類載入器來查詢給出描述名稱的類。
jclazz = addLocalReference(env, (Object*) clazz);
這行程式碼是增加類的引用計數。
bail:
free(descriptor);
JNI_EXIT();
return jclazz;
static jclass FindClass(JNIEnv* env, const char* name)
{
這個函式傳入兩個引數,第一個引數是jni的環境引數;第二個引數name是需要查詢的類描述名稱。
JNI_ENTER();
const Method* thisMethod;
ClassObject* clazz;
jclass jclazz = NULL;
Object* loader;
char* descriptor = NULL;
thisMethod = dvmGetCurrentJNIMethod();
assert(thisMethod != NULL);
這段程式碼是獲取當前正在執行的JNI載入方法。
descriptor = dvmNameToDescriptor(name);
if (descriptor == NULL) {
clazz = NULL;
goto bail;
}
這段程式碼是把查詢類的名稱轉換類描述的方式,以便從類索引表裡查詢到。
//Thread* self = dvmThreadSelf();
if (_self->classLoaderOverride != NULL) {
/* hack for JNI_OnLoad */
assert(strcmp(thisMethod->name, "nativeLoad") == 0);
loader = _self->classLoaderOverride;
這段程式碼是使用本執行緒過載載入方法,也就是使用 nativeLoad的本地方法。
} else if (thisMethod == gDvm.methFakeNativeEntry) {
/* start point of invocation interface */
if (!gDvm.initializing)
loader = dvmGetSystemClassLoader();
else
loader = NULL;
這段程式碼是使用系統裡的類載入器。
} else {
loader = thisMethod->clazz->classLoader;
這行程式碼是使用本類裡的載入器。
}
clazz = dvmFindClassNoInit(descriptor, loader);
這行程式碼是使用指定類載入器來查詢給出描述名稱的類。
jclazz = addLocalReference(env, (Object*) clazz);
這行程式碼是增加類的引用計數。
bail:
free(descriptor);
JNI_EXIT();
return jclazz;
}
//蔡軍生 2011-10-6
引用自:http://blog.csdn.net/caimouse/article/details/6846547