07/06
2013

Proguard语法及常用proguard.cfg代码段

本文主要ProGuard常用语法、标准proguard.cfg文件内容、常用proguard.cfg代码段及proguard与log level结合解决debug模式日志问题。关于ProGuard的作用、使用及bug分析可见ProGuard的作用、使用及bug分析

1、ProGuard的常用语法
-libraryjars class_path 应用的依赖包,如android-support-v4
-keep [,modifier,...] class_specification 不混淆某些类
-keepclassmembers [,modifier,...] class_specification 不混淆类的成员
-keepclasseswithmembers [,modifier,...] class_specification 不混淆类及其成员
-keepnames class_specification 不混淆类及其成员名
-keepclassmembernames class_specification 不混淆类的成员名
-keepclasseswithmembernames class_specification 不混淆类及其成员名
-assumenosideeffects class_specification 假设调用不产生任何影响,在proguard代码优化时会将该调用remove掉。如system.out.println和Log.v等等
-dontwarn [class_filter] 不提示warnning

关于proguard更多语法可见:http://proguard.sourceforge.net/index.html#manual/usage.html

 

2、标准proguard.cfg文件内容
参考android标准,修改如下:

源文件见<android_root>/build/core/proguard.flags , 将14行 -dontobfuscate解除注释。

 

3、常用proguard.cfg代码段

不混淆某类的构造方法,需指定构造函数的参数类型,如JSONObject

 

不混淆某个包所有类或某个类class、某个接口interface, 不混淆指定类则把**换成类名

 

不混淆指某个方法,*可换成指定的方法或类名

 

不混淆Parcelable的子类,防止android.os.BadParcelableException

 

添加android-support-v4.jar依赖包

 

4、proguard与log level结合解决debug模式Log问题
常见的Android debug日志的打法是定义一个静态变量DEBUG_STATUS,如果为true,则打印log,否则不打印。对于release模式该变量为false,debug模式变量为true。这里介绍一个更好的方法,不用担心正式发布时一不小心错改了该变量。

 

proguard的作用就是在release模式压缩、优化、混淆代码,其中的压缩和优化就包括去除不必要的代码,我们可以利用这一特性解决debug日志的问题,在proguard.cfg中添加

表示Log.d和Log.v代码无副作用,在proguard时会被从源码中remove掉,这样release模式(正式发布)就不会打印日志了,而debug模式(平常调试)照常打印,不用修改一点代码大赞吧,嘿嘿。当然这种方式有个弊端,如果使用拼接字符串方式,拼接的操作还是会存在的,如何优雅的屏蔽掉 Debug 版日志也可以参考:Android Debug 版本判断及为什么 BuildConfig.DEBUG 始终为 false

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

13 thoughts on “Proguard语法及常用proguard.cfg代码段

  1. 想请问下大神,就是混淆的时候有没有办法保证方法的参数名字不被混淆?比如void print(String name),混淆之后参数名字还是叫name,而不是param1之类的无具体含义的。

  2. 去除log的功能,虽然log没打出来,传递的参数还是会求值吧我测试用Log.d(TAG, f());, f()里两句话 System.err.println(“error test”); return “error test” + System.currentTimeMillis();,发现System.err.println还是执行了。有没有办法让Log.d的参数不求值