增加aapt2 “keep“ 规则的准确性

appt2工具会将你的Android应用资源打包成运行时的格式。它同时会生成 ProGuardR8需要的“keep” 规则,因此那些在资源文件中引用的类将不会被移除。一些类的例子如:仅在layout XML文件中引用的View,仅在menu XML文件中引用的 Action Provider 和仅在在AndroidManifest文件中引用的广播接收器,如果没有这些规则,它们将会在最终的APK文件中被删除。
Android Gradle plugin3.3.0-alpha05以前的版本,aapt2会生成针对这些类的构造方法生成一条使用通配符的“keep”规则。一些application、activity、view类的规则如下:

# Referenced at frontend/android/build/intermediates/merged_manifests/release/AndroidManifest.xml:20
-keep class com.jakewharton.sdksearch.SdkSearchApplication { <init>(...); }
# Referenced at frontend/android/build/intermediates/merged_manifests/release/AndroidManifest.xml:28
-keep class com.jakewharton.sdksearch.ui.MainActivity { <init>(...); }
# Referenced at search/ui-android/build/intermediates/packaged_res/release/layout/search.xml:57
-keep class android.support.v7.widget.RecyclerView { <init>(...); }

导出发布APK文件中的方法:

com.jakewharton.sdksearch.SdkSearchApplication <init>()
com.jakewharton.sdksearch.ui.MainActivity <init>()
android.support.v7.widget.RecyclerView <init>(Context)
android.support.v7.widget.RecyclerView <init>(Context, AttributeSet)
android.support.v7.widget.RecyclerView <init>(Context, AttributeSet, int)

SdkSearchApplicationMainActivity仅包含一个默认的构造方法,但RecyclerView却包含三个构造方法。如果仅考虑反射查找的需要,仅需要使用到一个构造方法。在manifest文件中引用的类仅会使用默认无参的构造方法。对于在layout文件中引用的类,仅有它的两个参数(Context,AttributeSet)的构造方法会被LayoutInflater调用。由于生成的规则为<init>(...),我们强制保留了所有的构造方法,尽管我们只需要一个。
Android Gradle plugin3.3.0-alpha05以后的版本中,新版本的aapt2被用来生成更精确的规则,这些规则仅保留反射查找所需要使用的构造方法。

# Referenced at frontend/android/build/intermediates/merged_manifests/release/AndroidManifest.xml:20
-keep class com.jakewharton.sdksearch.SdkSearchApplication { <init>(); }  
# Referenced at frontend/android/build/intermediates/merged_manifests/release/AndroidManifest.xml:28
-keep class com.jakewharton.sdksearch.ui.MainActivity { <init>(); }
# Referenced at search/ui-android/build/intermediates/packaged_res/release/layout/search.xml:57
-keep class android.support.v7.widget.RecyclerView { <init>(android.content.Context, android.util.AttributeSet); } 

现在再次导出发布APK文件中的方法:

com.jakewharton.sdksearch.SdkSearchApplication <init>()
com.jakewharton.sdksearch.ui.MainActivity <init>()
android.support.v7.widget.RecyclerView <init>(Context, AttributeSet)
android.support.v7.widget.RecyclerView <init>(Context, AttributeSet, int)

RecyclerView<init>(Context)构造方法不见了,那个被强制添加到release APK中尽管实际上并没有被使用到的构造方法。三个参数的构造方法仍然被保留,因为两个参数的构造方法会调用到它。

public RecyclerView(@NonNull Context context, @Nullable AttributeSet attrs) {
    this(context, attrs, 0);
}

如果开启优化选项并且没有其他规则使用到三个参数的构造方法,那么它将可能被内联,这个是在旧的规则中不可能发生的。
这看起来是一个比较小的变化,并且大部分情况下Application、activity和action provider子类型通常都仅包含一个构造方法,因此他们的计数好像没有变化。然而View的子类通常会有三个或者四个的构造方法,并且现在你将看到两到三个的构造方法被移除了。而在整个APK的范围内,将会有数十到上百个不在需要的方法被删除。由于特殊“keep”规则的增加,不仅是减少最终APK中原始的方法数,还使得优化器有更好的执行效果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值