一.背景
作为GP开发者,紧跟Google的脚步,升级开发环境和编译环境,不仅可以提升编译效率,新工具,新特性也是开发者们所期待的,当然随着工具的升级App的质量也会提升。所以,项目定期推进技术升级,显得很有必要。
项目中原有的一些配置
- Android Gradle Plugin(AGP)版本是
2.3.1
, - Gradle的版本为
gradle-3.5-all
, - Android Studio(3.1.3)
- JDK-7
此次的目标是升级到
- Android Gradle Plugin(AGP)版本是
3.1.4
, - Gradle的版本为
gradle-4.7-all
, - Android Studio(3.3 Canary 3)
- JDK-8
二.升级过程中遇到的问题:
整体来说AGP升级有很多需要改变的地方,每个项目中都会踩到不同的坑。所以我只是简单的从我们项目中遇到的问题介绍一下:
2.1 不在需要configuration传递,compiler替换成api或者implementation
- 升级以后,首先原来的compile变成了
api
,implementation
(当然还有其他几个,这里不细说)简单的来说,api
引进来的组件允许向上传递,implementation
引入进来的组件,不允许传递。其实就是访问隔离,当然也会提升编译速度。 -
configuration: 'release'
也会自动传递。无需在像下面这种写法来传递了。
releaseCompile project(configuration: 'release', path: ':xxx-base-framework')
debugCompile project(configuration: 'debug', path: ':xxx-base-framework')
api project(':xxx-base-framework')
2.2 Dex Knife
因为项目庞大
- Class的数量2.8万+
- Method的数量在17万+
Dex Knife 主要是解决Gradle2.3版本时,会出现Too many classes in --main-dex-list, main dex capacity exceeded
或者因为被挤出主Dex导致的类或者方法找不到问题。
当然当AGP升级到3.1.3之后,我们关闭了Dex Knife,让AGP自己去处理分包。效果还不错。暂时没出现问题。可能是有优化过吧。
dexOptions {
...
additionalParameters = [//dex参数详见 dx --help
'--multi-dex', //多分包
'--set-max-idx-number=55000', //每个包内方法数上限
//'--main-dex-list=' + projectDir +
//'/maindexlist.txt', //打包进主classes.dex的文件列表
//'--minimal-main-dex' //使上一句生效
...
]
}
同时开启D8之后,Dex Size从原来的12.4M降低到了11.9M。还是可以的。下面说说D8的BUG吧。
-
Before D8 总计12.4M
-
After D8 总计11.9M
2.3 D8 BUG
之前写的D8的相关文章:Android Studio 3.0+ 新Dex编译器D8与新混淆工具R8
当时因为编译不过暂时关闭了D8,(gradle.properties文件中增加:android.enableD8=false),我也在Google Issue提了相关的问题。科学上网: Provide better error message for syntax error in multiDexKeepFile 。
java.lang.RuntimeException: com.android.builder.dexing.DexArchiveMergerException: Error while merging dex archives:
app/build/intermediates/transforms/dexBuilder/othersAbroad/release/0.jar,
app/build/intermediates/transforms/dexBuilder/othersAbroad/release/2.jar,
app/build/intermediates/transforms/dexBuilder/othersAbroad/release/3.jar, app/build/intermediates/transforms/dexBuilder/othersAbroad/release/4.jar
这其实关系到一个流程,AGP先将Java代码混淆并编译成jar包放到上述目录位置。然后D8会根据maindexlist.txt(app/build/intermediates/multi-dex/othersAbroad/release/maindexlist.txt)里的配置,编译成dex文件。当然配置列表由AGP生成。自己项目中扩展的maindexlist.txt一会被追加到上面的这个build目录中的maindexlist中。
defaultConfig {
...
multiDexEnabled true
multiDexKeepFile file('multiDexKeep.txt')
...
}
是因为我在multiDexKeep.txt
中的错误写法如下:
com.xxx.xxx.SplashActivity.class
com.xxx.xxx.MainActivity.class
正确写法:
com/xxx/xxx/SplashActivity.class
com/xxx/xxx/MainActivity.class
开发者网站配置方法数超过 64K 的应用文章中是有提到的,只是在真正build的时候DX是直接忽略掉,D8是提示报错。但是没有准确提示。
2.4 aapt2的问题
这个问题很直接
- 错误写法:
<resources>
<style name="popup_animation">
<item name="@android:windowEnterAnimation">@anim/popup_show</item>
<item name="@android:windowExitAnimation">@anim/popup_hide</item>
</style>
</resources>
- 正确写法:
<resources>
<style name="popup_animation">
<item name="android:windowEnterAnimation">@anim/popup_show</item>
<item name="android:windowExitAnimation">@anim/popup_hide</item>
</style>
</resources>
好吧,到底改了什么?把android:windowEnterAnimation
前面的@去掉吧。