从前面我们知道,在虚拟机初始化后,运行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;

}


//QQ:9073204 EMAIL:9073204@qq.com

//蔡军生  2011-10-6


Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐