利用Proguard移除无用代码以及碰到的坑
0x00 起因
今天用反编译工具反编译了下App,如图:
可以看到,里面用来打印生命周期的代买还在里面,虽然说我们一般会封装成log的工具类,然后利用 BuildConfig.DEBUG 来判断是否打印日志,但是这种也太low了是吧?毕竟对于有洁癖的人来说还是多了个空方法,看着不爽。
0x01 解决过程
由于之前没看到过相关资料,因此只能搜索,历经切换了多次关键字后终于发现了Proguard中 -assumenosideeffects 这个参数,通过配置可以在 release 中移除某些代码。
具体配置是:
必须是Release模式并且 minifyEnabled 置为 true ,这样才会使用 Proguard 混淆
在本Module的混淆配置文件 proguard-rules.pro 中增加下面的代码:
-assumenosideeffects class android.util.Log {
public static *** d(...);
public static *** e(...);
public static *** i(...);
public static *** v(...);
public static *** println(...);
public static *** w(...);
public static *** wtf(...);
}
确保混淆配置文件中没有关闭压缩,也就是说不要有 -dontoptimize 这个配置
你以为到这里就结束了?呵呵,TYTN! 我按照这个打包了好多次,就是没有效果,三个关键点比对了好多次,就是没效果。后来,终于找到了原因,原来 buildTypes 中的 release 中是这样写的:
release {
minifyEnabled true
zipAlignEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
注意,问题就出在 getDefaultProguardFile('proguard-android.txt') 这里,这里的 proguard-android.txt 指向的是 SDK 中 sdk_dir/tools/proguard/proguard-android.txt ,这里面有一句:
问题就在这里,去掉这里或者直接在 buildTypes 移除缺省的配置(前提是保证自定义的配置是完整的满足混淆的)即可。
0x02 最后
关于 -assumenosideeffects 这个参数如何能移除代码、能移除哪些类型的可参考下面的第一篇资料。 最后奉上处理后的代码:
是不是干净多了?
0x03 补充
上面最终结果的图中,圈出来了两个地方:
第一个,由于开启代码优化,因此 Proguard 就把代码中的一个静态方法直接内联到调用的地方了(类似C++的内联函数)
有些log里面的变量是没法去掉的,因此会多一个无用的字符串,具体参考第一个参考资料。
祝大家愉快!!!
0x04 参考资料
0x05 关于
Author peerless2012