Android Gradle 编译过程中的优化
2019-07-31 09:21:16
在使用Gradle编译APK的release时,会习惯在buildTypes的release标签中加上如下配置:
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile(‘proguard-android.txt’), ’proguard-rules.pro’
}
其中minifyEnabled和shrinkResources就是优化的开关,当这两个开关都打开时,APK编译的时候会进行如下优化流程:
下面重点介绍下上述各流程中所做的优化。
其中library中的没有被调用的class文件将被删除。
shrink code过程需要知道入口点,换言之就是shrink code需要知道哪些类是入口类,然后按照这个入口类建立调用链确定哪些类,方法,属性和变量是没有被使用。
-keepclasseswithmembernames class * {
native <methods>;
}
但是反射没有办法能很好的识别,所以如果代码中有使用反射需要自行处理,以免被删除。
1.通过Resources.getIdentifier()动态获取资源,当shrink resource删除资源时会对该API调用进行模糊匹配,反是匹配上的都不会删除,例如:
String name = String.format(“img_%1d”, angle + 1);
res = getResources().getIdentifier(name, ”drawable”, getPackageName());
所有img_开头的图片资源都会被认为有调用,不会被删除
2.通过tools:keep标签主动标记,防止删除。通过创建res/raw/keep.xml文件并且在该文件中主动标记防止删除,如下所示:
<?xml version=”1.0″ encoding=”utf-8″?>
<resources xmlns:tools=”http://schemas.android.com/tools”
tools:keep=”@layout/l_used*_c,@layout/l_used_a,@layout/l_used_b*”/>
obfuscate 将类,方法,属性和变量重命名为短小且无意义的名字,减小包体积并且进行代码防护,Gradle 3.4及以后AndroidStudio不再使用ProGuard进行混淆,而是使用R8插件进行,但是会保留ProGuard的配置选项。
optimize为优化代码过程,会直接修改代码逻辑,如if判断始终为true时则会删除if判断和false代码块;当一个类只有一个方法且只有一处调用则会删除这个类并且将方法内链。
optimize过程能进一步缩减包大小
充分理解Gradle编译过程中的优化流程有重要的意义,对我们APK优化有很大的启发,如微信对外开放的混淆资源名减小安装包大小的功能,同时对release 包出现的不一致现象能快速定位问题并且解决。
扫描二维码分享到微信