程序猿葵花宝典移动知识

Android Dex分包原理

2018-07-10  本文已影响178人  会撒娇的犀犀利

为什么要分包?

1、65536问题

2、怎么解决这个问题

multiDexEnabled true
@Override protected void attachBaseContext (Context base) {
    super.attachBaseContext(base);
    MultiDex.install(this);
}

分包导致的问题

  1. API14 之前的不能支持分包 Dalvik linearalloc bug

  2. 在冷启动时因为需要安装dex文件,如果dex文件过大时,处理时间过长,很容易引发ANR(Application Not Responding);

  3. 采用MultiDex方案的应用因为需要申请一个很大的内存,在运行时可能导致程序的崩溃,这个主要是因为Dalvik linearAlloc 的一个限制,这个限制在 Android 4.0 (API level 14)已经增加了, 应用也有可能在低于 Android 5.0 (API level 21)版本的机器上触发这个限制;

  4. 分包后,不同依赖项目间的dex文件函数相互调用,报错找不到方法

Android系统对分包的影响

MultiDex的基本原理

通过DexFile来加载Secondary DEX,并存放在BaseDexClassLoaderDexPathList中。

解决分包导致调用找不到对应类

1、微信加载方案

首次加载在地球中页中, 并用线程去加载(但是 5.0 之前加载 dex 时还是会挂起主线程一段时间(不是全程都挂起))。

总的来说,这种方案用户体验较好,缺点在于太过复杂,每次都需重新扫描依赖集,而且使用的是比较大的间接依赖集。

2、 Facebook 加载方案

Facebook的思路是将 MultiDex.install() 操作放在另外一个经常进行的。

  <activity 
    android:exported="false"
    android:process=":nodex"
     android:name="com.facebook.nodex.startup.splashscreen.NodexSplashActivity">

所有的依赖集为 Application、NodexSplashActivity 的间接依赖集即可。

这种方式好处在于依赖集非常简单,同时首次加载 dex 时也不会卡死。但是它的缺点也很明显,即每次启动主进程时,都需先启动 nodex 进程。尽管 nodex 进程逻辑非常简单,这也需100ms以上。

3、美团加载方案


    tasks.whenTaskAdded { task ->
     if (task.name.startsWith('proguard') && (task.name.endsWith('Debug') || task.name.endsWith('Release'))) {
     task.doLast {
     makeDexFileAfterProguardJar();
     }
     task.doFirst {
     delete "${project.buildDir}/intermediates/classes-proguard";

     String flavor = task.name.substring('proguard'.length(), task.name.lastIndexOf(task.name.endsWith('Debug') ? "Debug" : "Release"));
     generateMainIndexKeepList(flavor.toLowerCase());
     }
     } else if (task.name.startsWith('zipalign') && (task.name.endsWith('Debug') || task.name.endsWith('Release'))) {
     task.doFirst {
     ensureMultiDexInApk();
     }
     }
    }

美团的这种方式对主 dex 的要求非常高,因为第二个 dex 是等到需要的时候再去加载。重写Instrumentation 的 execStartActivity 方法,hook 跳转 Activity 的总入口做判断,如果当前第二个 dex 还没有加载完成,就弹一个 loading Activity等待加载完成。

最后,希望此篇博客对大家有所帮助,欢迎提出问题及建议共同探讨,如有兴趣可以关注我的博客,谢谢!

上一篇下一篇

猜你喜欢

热点阅读