接着下来,来分析怎么样加载方法的代码,loadMethodFromDex函数的代码如下:

staticvoidloadMethodFromDex(ClassObject*clazz, const DexMethod*pDexMethod,

Method*meth)

{

这个函数传入三个参数,第一个参数clazz是类相关信息;第二个参数pDexMethod是要加载的方法相关信息;第三个参数meth是指向加载的方法,也就是可以运行的代码。


DexFile*pDexFile = clazz->pDvmDex->pDexFile;

这行代码是获取Dex文件。


constDexMethodId*pMethodId;

constDexCode*pDexCode;


pMethodId =dexGetMethodId(pDexFile, pDexMethod->methodIdx);

这行代码是从Dex文件里通过索引获取到方法的ID。


meth->name= dexStringById(pDexFile, pMethodId->nameIdx);

这行代码是获取方法的名称。


dexProtoSetFromMethodId(&meth->prototype,pDexFile, pMethodId);

meth->shorty= dexProtoGetShorty(&meth->prototype);

meth->accessFlags= pDexMethod->accessFlags;

meth->clazz= clazz;

meth->jniArgInfo= 0;

这段代码是设置方法的属性。



if(dvmCompareNameDescriptorAndMethod("finalize","()V",meth) == 0) {

SET_CLASS_FLAG(clazz,CLASS_ISFINALIZABLE);

}

这段代码是判断是否最后退出函数,如果是退出函数就设置标志。



pDexCode =dexGetCode(pDexFile, pDexMethod);

这行代码是获取方法执行代码,如果是本地方法或者抽像函数返回空。


if(pDexCode != NULL) {

/*integer constants, copy over for faster access */

meth->registersSize= pDexCode->registersSize;

meth->insSize= pDexCode->insSize;

meth->outsSize= pDexCode->outsSize;


/*pointer to code area */

meth->insns= pDexCode->insns;

这段代码是从Dex文件里获取到方法的代码,保存相应的方法结构里,以便后面使用。


} else{

/*

* We don't have a DexCodeblock, but we still want to know how

* much space is neededfor the arguments (so we don't have to

* compute it later). Wealso take this opportunity to compute

* JNI argument info.

*

* We do this for abstractmethods as well, because we want to

* be able to substituteour exception-throwing "stub" in.

*/

intargsSize = dvmComputeMethodArgsSize(meth);

这行代码是计算方法参数大小。


if(!dvmIsStaticMethod(meth))

argsSize++;

这段代码是静态方法需要增加参数。


meth->registersSize= meth->insSize= argsSize;

assert(meth->outsSize== 0);

assert(meth->insns== NULL);


if(dvmIsNativeMethod(meth)) {

meth->nativeFunc= dvmResolveNativeMethod;

meth->jniArgInfo= computeJniArgInfo(&meth->prototype);

}

这段代码是处理本地方法的调用。


}

}


到这里,就可以把每个方法的代码解释出来,获取到方法所有的相关信息,这样就可以备运行条件了。

更多相关文章

  1. Picasso源码分析
  2. Android(安卓)控件 拖动
  3. Android中使用OnClickListener接口实现按钮点击的低级失误
  4. [置顶] android中屏幕触摸事件
  5. 【Android】通过Java代码替换TabHost中的drawableTop资源
  6. Android获取视频文件某一帧并设置图片
  7. Android文件储存
  8. Android(安卓)Sensor框架简述(三)
  9. Android培训班(72)Dex文件里类定义dvmDefineClass

随机推荐

  1. android监听手机网络连接状态改变的后台
  2. android 上下左右手势判断 根据别人的改
  3. android listView
  4. Android复习(十)
  5. Android核心基础(四)
  6. Android(安卓)封装http请求的工具类
  7. android 監聽系統屬性變化的方法
  8. Android常用的工具类-收藏用
  9. Android(安卓)单位
  10. Android使用HttpURLConnection提交数据