Android自定义MyApplication偶发未创建问题排查求助
兄弟,我之前也踩过类似Multidex导致Application偶尔“失踪”的坑,结合你的配置(targetSdk23、compileSdk26、multidex1.0.1),大概率是这几个原因,给你梳理下解决办法:
1. 主dex没把MyApplication“安排”进去
应用启动时系统只会先加载主dex里的类,如果你的MyApplication或者它依赖的类没被打包进主dex,就会出现系统找不到它的情况——之所以非必现,是因为打包时的类索引有时候会随机把它放进去,有时候不会。
怎么解决:
手动强制把MyApplication塞进主dex,在app/build.gradle里加这些配置:
android { defaultConfig { // 你的原有配置不动,加上这行 multiDexEnabled true } buildTypes { release { // 原有配置不动,加这两行 multiDexKeepFile file('multidex-config.txt') multiDexKeepProguard file('multidex-config.pro') } debug { // debug模式也得加,不然调试时也会踩坑 multiDexKeepFile file('multidex-config.txt') multiDexKeepProguard file('multidex-config.pro') } } }
然后在app模块目录下建两个文件:
multidex-config.txt:直接写要进主dex的类路径
com/my/app/MyApplication.class
multidex-config.pro:用ProGuard规则锁死,不让它被混淆也不让它跑别的dex里
-keep class com.my.app.MyApplication { *; } -keep class android.support.multidex.** { *; }
2. 你用的multidex版本太老了
1.0.1这个版本是好几年前的了,针对targetSdk23的系统有不少兼容性问题没修复,升级下版本准没错。
怎么升级:
如果还是用support库的话,升到最新稳定版:
implementation 'com.android.support:multidex:1.0.3'
要是已经迁AndroidX了,就换AndroidX的multidex:
implementation 'androidx.multidex:multidex:2.0.1'
3. 启动时类加载“抢跑”了
有时候Multidex初始化和Application的初始化会有竞争,尤其是应用启动时还有其他组件(比如ContentProvider)优先加载,要是这些组件的类不在主dex里,就会导致Multidex还没初始化完就加载了其他dex的类,间接把MyApplication的初始化搞崩了。
怎么优化:
先把MyApplication的代码改得健壮点,加个异常捕获,避免直接崩:
public class MyApplication extends Application { @Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); // 加个try-catch,万一Multidex初始化失败也能记录日志 try { MultiDex.install(this); } catch (RuntimeException e) { e.printStackTrace(); // 这里可以加个自定义日志,方便后续排查 } } @Override public void onCreate() { super.onCreate(); // 所有全局初始化代码都放这儿,确保Multidex已经初始化完了 } }
另外,检查下AndroidManifest里有没有配置启动时优先加载的组件(比如ContentProvider),这些组件的类也得加到刚才的multidex-config.txt里,确保它们也在主dex里。
4. 验证下主dex里到底有没有MyApplication
要是做完上面的操作还没解决,你可以手动检查主dex的内容:
用Android SDK里的dx工具(路径一般在sdk/build-tools/你的build-tools版本/dx),执行这条命令:
dx --dex --dump-to=main-dex-list.txt --dump-width=1000 app/build/intermediates/transforms/dexBuilder/release/0/mainDexClasses.jar
打开生成的main-dex-list.txt,搜一下com.my.app.MyApplication,要是找不到,说明之前的配置没生效,得再调整下。
内容的提问来源于stack exchange,提问作者Cottonfloss

