alighters

程序、写作、人生

Multidex 的问题

| Comments

降低启动速度的问题

文章中提到的一点,在 Android 设备 4.4 及其之前的版本,当开启 Multidex 的时候,启动速度会延长 15% 。而 5.0及以上的设备因使用 ART 的方式,其默认支持多 dex 的加载。

NoClassDefFoundError 的问题

  • 查看加载的类问题 在目录 [buildDir]/intermediates/multi-dex/[buildType]/maindexlist.txt 中可查看在主 dex 文件中的类,(但并不是 100% 准确,可能会丢失一些类)
  • 解决办法:配置一个新的 multidex.keep 文件,用来指定在 mainDex 中包含的类。通过配置 gradle 文件,指定 gradle 打包过程中,执行 dex 生成时的 keep 文件追加。具体实施是创建一个新的 task,使用 finalizedBy 来指定在 create**MainDexClassList 任务之后执行。另外还需要指定 dx 执行时,添加 —minimal-main-dex 选项,来使 maindex 最小化。

如何判断 App 启动过程中哪些类是需要加载的呢?

通过使用类加载 ClassLoader 中,其提供了方法 findLoadedClass。这个方法的作用是用来判断某个类是否被加载,所以文章中使用的技巧就是通过读在 second dex files 中的类,来判断主 dex 是否加载到。若是加载到,则我们就需要将这个类添加至 main dex 来提高 App 的启动速度。

解决与建议

出现 65k 的问题时候,通过其他方式(重构、优化第三方 SDK的使用)来尽量避免使用 Multidex;若是不可避免地使用,需要对 Multidex 的方式进行优化来使用,来尽量提高我们 App 的启动速度。

延迟加载

对纯 java 文件,可以将其单独打成一个 dex,利用 Multidex 加载的原理,在当我们使用到相应 java 文件的时候,再加载这个 dex,来执行相应代码的调用。(方案有些不成熟,不支持涉及到资源文件的情况。)

其他

1. 工具 ClassShark

在评论区,提到的一个软件 android-classyshark,可以帮我们更加容易分析 APK、dex、jar 中的使用内容,(不再通过 dex2jar, jd-gui等工具来查看)能够对 apk 中的内容一目了然, 功能非常强大。

在 Android Studio 2.2 之后的版本,其已经支持了对 apk 的分析,可以直接点击进行查看。

2. dex2oat 与 dexopt

评论中关于 5.0及以上不受影响的讨论,主要原因是因为 5.0 采用了 ART 的编译方式,其是在 app 安装的时候执行的,期间对 dex 文件采用了 dex2oat 的执行过程,来对 dex 文件进行优化。而 5.0 之前的设备是没有这一步,其采用的 dexopt 的过程,并处理的是单个 dex 文件,这样也会影响了 multidex 的启动速度,但是这个是每次打开 app 都会进行的,并不是安装时执行的。

作者的关注点是在每次 App 打开的过程中, Multidex 带来的影响,所以这个讨论在这里并不是与主题太多相关,但是我们还是又必要了解一下的。

参考资料

版权归作者所有,转载请注明原文链接:/blog/2016/11/01/multidex-problems/

给 Ta 个打赏吧...

Comments