昨天简单介绍了Proguard的使用过程,与Eclipse结合使用操作过程很简单,有需要的朋友可以参考昨天的文章。混淆器的使用最难的就是关键词的设置。配置文件的关键词有其独特的设置格式。不同于java代码,需要静下心来研究。今天主要介绍一下配置文件中常用到的关键词命令。
-
压缩(Shrinking):默认开启,用以减小应用体积,移除未被使用的类和成员,并且会在优化动作执行之后再次执行(因为优化后可能会再次暴露一些未被使用的类和成员)。
-dontshrink 关闭压缩 -
优化(Optimization):默认开启,在字节码级别执行优化,让应用运行的更快。
-dontoptimize 关闭优化
-optimizationpasses n 表示proguard对代码进行迭代优化的次数,Android一般为5
-
混淆(Obfuscation):默认开启,增大反编译难度,类和类成员会被随机命名,除非用keep保护。
-dontobfuscate 关闭混淆 -
基本规则:
-keep class com.pingan.test.**
-keep class com.pingan.test.*
对于和两个比较常用的命令,初次接触会比较迷糊,这两者什么区别呢?其实理解了就很简单,一个*表示只保留该包名下的类名不被混淆,而子包下的类名会被混淆,两个*表示本包和包所含子包下的类名都保持不混淆,这两个方法使用之后,你会发现类名虽然未被混淆,但类里面的具体方法和变量命名还是被混淆了。若果既想保持类名又想保持内容不被混淆,则需要下面命令:
-keep class com.pingan.test.* {*;}
-
通过上面-keep的基本用法,我们可以使用Java的基本规则来保护特定类不被混淆,就是昨天列举的extend,implement等这些Java规则。如下例子就避免所有继承Activity的类被混淆
-keep public class * extends android.app.Activity
如果我们要保留一个类中的内部类不被混淆则需要用$符号,如下例子表示保持ScriptFragment内部类JavaScriptInterface中的所有public内容不被混淆。
-keepclassmembers class cc.ninty.chat.ui.fragment.ScriptFragment$JavaScriptInterface {
public *;
}
-
如果一个类中你不希望保持全部内容不被混淆,而只是希望保护类下的特定内容,就可以使用
<init>; //匹配所有构造器
<fields>; //匹配所有域
<methods>; //匹配所有方法方法
在<fields>或<methods>前面加上private 、public、native等来进一步指定不被混淆的内容,如
-keep class cn.hadcn.test.One {
public <methods>;
}
-
表示One类下的所有public方法都不会被混淆,当然你还可以加入参数,比如以下表示用JSONObject作为入参的构造函数不会被混淆:
-keep class cn.hadcn.test.One {
public <init>(org.json.JSONObject);
}
8.有时不需要保持类名,只想把该类下的特定方法保持不被混淆就好,那你就不能用keep方法了,keep方法会保持类名,而需要用keepclassmembers ,如此类名就不会被保持,为了便于对这些规则进行理解,官网给出了以下表格:
移除是指在压缩(Shrinking)时是否会被删除。以上内容时混淆规则中需要重点掌握的,了解后,基本所有的混淆规则文件你应该都能看懂了。
这些基本规则明白之后,还有几点注意事项,比如jni方法不能混淆,反射用到的类不能混淆,与服务器交互式,使用GSON解析服务端数据时所写的GSON类不能混淆,具体问题等大家遇到时可百度。我也是参考前辈文章签名打包成功的,由于不能发外链,所以只能我再捯饬一边了。
今天就分享到这里,祝大家好运!