1. 程式人生 > >在native執行緒利用JNI 反射自定義類--ndk開發參考2

在native執行緒利用JNI 反射自定義類--ndk開發參考2

從前面我們知道,在虛擬機器初始化後,執行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;

}

//蔡軍生  2011-10-6

引用自:http://blog.csdn.net/caimouse/article/details/6846547