Android培训班(74)Dalvik虚拟机的FindClass函数
从前面我们知道,在虚拟机初始化后,运行Java代码的方法时,要先查找到类,也就是调用函数FindClass。接着后面分析怎么样从dex文件加载类数据到内存,现在开始对查找函数FindClass进行分析,就很好理解了,因为前面介绍加载类到内存的流程已经很清楚。函数FindClass
·
从前面我们知道,在虚拟机初始化后,运行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;
}
//QQ:9073204 EMAIL:9073204@qq.com
//蔡军生 2011-10-6
更多推荐
已为社区贡献30条内容
所有评论(0)