首页
社区
课程
招聘
[求助]关于Android加壳之内存加载dex的几点疑问
发表于: 2015-11-30 17:15 6159

[求助]关于Android加壳之内存加载dex的几点疑问

2015-11-30 17:15
6159
参考了Jack_jia的Android4.0内存Dex数据动态加载技术,同时参考另一片文章[链接]具体内容就不赘述了。

实现这个的原因一是内存加载更加安全,二是听说这种方法可以加速程序的启动,加壳后的程序启动实在太慢了。

1. 按照Jack_jia的方法自己实现以后,运行的过程中出现类似 Caused by: java.lang.ClassCircularityError: android/support/v4/app/ActivityCompat21$SharedElementCal 这种错误,应该是循环依赖,但是不太明白是怎么回事,研究了半天,找到下面的代码:

     protected Class<?> findClass(String name) throws ClassNotFoundException {
               Log.d(TAG, "findClass-" + name);
               Class<?> cls = null;

               String as[] = getClassNameList(cookie);
               for (int z = 0; z < as.length; z++) {
                        if (as[z].equals(name)) {
                                 cls = defineClass(as[z].replace('.', '/'),
                                                    mContext.getClassLoader(), cookie);
                        } else {
                                 defineClass(as[z].replace('.', '/'), mContext.getClassLoader(),
                                                    cookie);
                        }

               }

               if (null == cls) {
                        cls = super.findClass(name);
               }

               return cls;
     }

  这段代码是自己实现的DexClassLoader中的重写findClass方法的代码,然后我把其中那段红色的代码注释掉以后运行就正常了。看了下Android系统源码还是不太明白defineClass的作用。

2. 按照上面的方法虽然运行正常了,但是启动速度非常的慢,按说这种方法应该可以让程序启动的快一些才对,不知道是哪里不对。

3.  另外还有一点就是在java层实现自己的DexClassLoader的时候利用java反射机制调用了DexFile类的getClassNameList方法和defineClass方法,而在C层去查找Dalvik_dalvik_system_DexFile_openDexFile_bytearray这个方法并利用它来加载dex文件,而这个函数实际上就是对应java层的DexFile类的openDexFile函数,那为什么不直接用java反射机制调用DexFile类的openDexFile函数就好了,干嘛还那么麻烦去找它的C层实现呢?

以上三个问题困扰我很久了,希望大神们不吝赐教啊,小弟谢过了!

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (3)
雪    币: 7818
活跃值: (1073)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
2
1、defineClass就是加载对应的classObject,每次只加载自己对应的类就ok,所以我觉得不需要else后面的代码。
2、因为继承了DexClassLoader,在调用了super(oriPath, fakePath, libraryPath, parent);继续跟踪代码发现,还是执行了优化dex,所以还是耗时。不耗时,就得直接加载dex,参考http://bbs.pediy.com/showthread.php?t=205577。
3、因为4.4已经把java层的openDexFile移除了,在这个版本就不能通过反射获取这个方法了,为了通用型,所以才这么大费周折。
2015-12-2 08:59
0
雪    币: 15
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
非常感谢你的回答,对于你的回答:“2、因为继承了DexClassLoader,在调用了super(oriPath, fakePath, libraryPath, parent);继续跟踪代码发现,还是执...”
这里的super传进去的dex路径是壳程序的路径,所以应该不会执行dexopt的优化,我实现的原理和你发的那个链接里的方法是一样的,但就是不知道为什么这么慢,有可能是在defineClass的那个循环里没有break吧,我改一下看看怎么样。

多谢!
2015-12-2 17:01
0
雪    币: 7818
活跃值: (1073)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
4
public DexClassLoader(String dexPath, String optimizedDirectory,
           String libraryPath, ClassLoader parent) {
       super(dexPath, new File(optimizedDirectory), libraryPath, parent);
}
继续执行
public BaseDexClassLoader(String dexPath, File optimizedDirectory,
        String libraryPath, ClassLoader parent) {
        super(parent);
        this.pathList = new DexPathList(this, dexPath, libraryPath, optimizedDirectory);
}
继续执行
在DexPathList构造函数中调用了makeDexElements,makeDexElements又调用了loadDexFile,loadDexFile调用了 DexFile.loadDex,这个方法走进了native方法里面,先优化,再形成Dexfile结构。
2015-12-4 08:57
0
游客
登录 | 注册 方可回帖
返回
//