项目上线中发现报出很多FileProvider子类的java.lang.ClassNotFoundException,其中有一个特定子类报错最多,分析apk文件发现该类其实是存在dex中的,只是不在主dex中,怀疑是因为Provider加载时机很早,在Application类onCreat方法调用前就被系统初始化,但是因为某些原因不在主dex中所以报错,尝试将该类打入主dex中,但是看了很多资料发现都已经过时了,所提供的方法已经失效,根据官方文档我们应该这样做:
- 修改模块级 build.gradle 文件以启用多 dex 文件,并将多 dex 文件库添加为依赖项,如下所示(注意:本文所做的修改建立在假设你的应用已经支持多Dex分包的前提下):
android {
defaultConfig {
...
minSdkVersion 15
targetSdkVersion 28
multiDexEnabled true
//根据官方文档描述,指定该文件可以以Proguard 格式和语法指定符合规则的类打入主dex类中,我没有使用这个,如果你不需要,可以注释或不添加,这种写法需要清单文件与build.gradle文件在同一层级,也就是该模块的根目录下。
multiDexKeepProguard file('multiDexKeep.pro')
//指定一个清单文件,在清单文件中以单个文件格式添加需要打入主dex的包,这种写法需要清单文件与build.gradle文件在同一层级,也就是该模块的根目录下。
multiDexKeepFile file('main-dex-list.txt')
}
...
}
dependencies {
//注意这里使用的是Androidx的包
implementation 'com.android.support:multidex:1.0.3'
}
如下,我们指定的main-dex-list
文件的位置:
如下,我们指定的main-dex-list
文件的格式:
com/xxx/webview/extension/utils/FileProvider.class
com/sensorsdata/analytics/android/sdk/SensorsDataContentProvider.class
android/support/multidex/BuildConfig.class
android/support/multidex/MultiDex$V14.class
android/support/multidex/MultiDex$V19.class
android/support/multidex/MultiDex$V4.class
android/support/multidex/MultiDex.class
android/support/multidex/MultiDexApplication.class
android/support/multidex/MultiDexExtractor$1.class
android/support/multidex/MultiDexExtractor.class
android/support/multidex/ZipUtil$CentralDirectory.class
android/support/multidex/ZipUtil.class
根据我实际操作的情况,我们指定的main-dex-list
最终会被合入build后生成的mainDexList
,而不是和有的文章描述的那样需要把生成的mainDexList
拷出来加入自己需要的类,有的文章可能会告诉你在app\build\intermediates\multi-dex\debug
下可以找到这个类,但实际上新版本的Gradle中我们需要在app\build\intermediates\legacy_multidex_main_dex_list\debug\transformClassesWithMultidexlistForDebug\mainDexList.txt
路径下才能找到这个文件,以及更多的和multiDex
、分包
相关的信息,可以参阅Android开发者官网:启用多 dex 处理。