proguard.cfg(转载)
来源:互联网 发布:尘埃3 for mac 编辑:程序博客网 时间:2024/04/27 21:12
ProGuard简介
ProGuard是一个SourceForge上非常知名的开源项目。官网网址是:http://proguard.sourceforge.net/。
Java的字节码一般是非常容易反编译的。为了很好的保护Java源代码,我们往往会对编译好的class文件进行混淆处理。ProGuard的主要作用就是混淆。当然它还能对字节码进行缩减体积、优化等,但那些对于我们来说都算是次要的功能。
引用ProGuard官方的一段话来介绍就是:
ProGuard is a free Java class file shrinker, optimizer, obfuscator, and preverifier. It detects and removes unused classes, fields, methods, and attributes. It optimizes bytecode and removes unused instructions. It renames the remaining classes, fields, and methods using short meaningless names. Finally, it preverifies the processed code for Java 6 or for Java Micro Edition.
Android Eclipse开发环境与ProGuard
在Android 2.3以前,混淆Android代码只能手动添加proguard来实现代码混淆,非常不方便。而2.3以后,Google已经将这个工具加入到了SDK的工具集里。具体路径:SDK\tools\proguard。当创建一个新的Android工程时,在工程目录的根路径下,会出现一个proguard的配置文件proguard.cfg。也就是说,我们可以通过简单的配置,在我们的elipse工程中直接使用ProGuard混淆Android工程。
具体混淆的步骤非常简单。首先,我们需要在工程描述文件default.properties中,添加一句话,启用ProGuard。如下所示:
2 # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 #
4 # This file must be checked in Version Control Systems.
5 #
6 # To customize properties used by the Ant build system use,
7 # "build.properties", and override values to adapt the script to your
8 # project structure.
9 # Indicates whether an apk should be generated for each density.
10 split.density=false
11 # Project target.
12 target=android-10
13 proguard.config=proguard.cfg
14
这样,Proguard就可以使用了。当我们正常通过Android Tools导出Application Package时,Proguard就会自动启用,优化混淆你的代码。
导出成功后,你可以反编译看看混淆的效果。一些类名、方法名和变量名等,都变成了一些无意义的字母或者数字。证明混淆成功!
proguard.cfg配置
稍微深入想一下混淆后的结果,你就会发现,如果一些提供给外部的类、方法、变量等名字被改变了,那么程序本身的功能就无法正常实现。那么Proguard如何知道哪些东西是可以改名,而哪些是不能改变的呢?
这个是靠proguard.cfg文件来进行配置的。Android工程中默认自动生成的proguard.cfg已经针对Android的一般情况进行了配置,我们打开这个配置文件。内容大概如下:
2 -dontusemixedcaseclassnames
3 -dontskipnonpubliclibraryclasses
4 -dontpreverify
5 -verbose
6 -optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
7 -keep public class * extends android.app.Activity
8 -keep public class * extends android.app.Application
9 -keep public class * extends android.app.Service
10 -keep public class * extends android.content.BroadcastReceiver
11 -keep public class * extends android.content.ContentProvider
12 -keep public class * extends android.app.backup.BackupAgentHelper
13 -keep public class * extends android.preference.Preference
14 -keep public class com.android.vending.licensing.ILicensingService
15
16 -keepclasseswithmembernames class * {
17 native <methods>;
18 }
19
20 -keepclasseswithmembernames class * {
21 public <init>(android.content.Context, android.util.AttributeSet);
22 }
23
24 -keepclasseswithmembernames class * {
25 public <init>(android.content.Context, android.util.AttributeSet, int);
26 }
27
28 -keepclassmembers enum * {
29 public static **[] values();
30 public static ** valueOf(java.lang.String);
31 }
32
33 -keep class * implements android.os.Parcelable {
34 public static final android.os.Parcelable$Creator *;
35 }
36
它主要保留了继承自Activity、Application、Service、BroadcastReceiver、ContentProvider、BackupAgentHelper、Preference和ILicensingService的子类。因为这些子类,都是可能被外部调用的。
另外,它还保留了含有native方法的类、构造函数从xml构造的类(一般为View的子类)、枚举类型中的values和valueOf静态方法、继承Parcelable的跨进程数据类。
在实际的一个工程项目中,可能Google自动生成的配置不能胜任我们的混淆工作。所以,我们往往需要自己编写一些ProGuard配置。这方面的资料在官网的Manual -> Usage里有详细说明。大家可以研究一下。
--------------------------------------------------------------------------------------------------
-injars androidtest.jar【jar包所在地址】
-outjars out【输出地址】
-libraryjars 'D:\android-sdk-windows\platforms\android-9\android.jar' 【引用的库的jar,用于解析injars所指定的jar类】
-optimizationpasses 5
-dontusemixedcaseclassnames 【混淆时不会产生形形色色的类名 】
-dontskipnonpubliclibraryclasses 【指定不去忽略非公共的库类。 】
-dontpreverify 【不预校验】
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* 【优化】
-keep public class * extends android.app.Activity 【不进行混淆保持原样】
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService
-keep public abstract interface com.asqw.android.Listener{
public protected <methods>; 【所有方法不进行混淆】
}
-keep public class com.asqw.android{
public void Start(java.lang.String); 【对该方法不进行混淆】
}
-keepclasseswithmembernames class * { 【保护指定的类和类的成员的名称,如果所有指定的类成员出席(在压缩步骤之后)】
native <methods>;
}
-keepclasseswithmembers class * { 【保护指定的类和类的成员,但条件是所有指定的类和类成员是要存在。】
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers class * extends android.app.Activity {【保护指定类的成员,如果此类受到保护他们会保护的更好 】
public void *(android.view.View);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable {【保护指定的类文件和类的成员】
public static final android.os.Parcelable$Creator *;
}
参考:http://blog.csdn.net/vrix/article/details/7100841
加入第三方jar包之后常出现的几个异常:
proguard returned with error code 1.See console
情况1:
Proguard returned with error code 1. See console
Error: C:/Documents (系统找不到指定文件)
后来发现是因为将整个工程放到了桌面上,而桌面的目录是C:/Documents and Settings/Administrator/桌面,在这里面有空格,而proguard进行发编译的时候是不允许有空格的
如果换了正确路径还不好用的话,直接删除proguard就好了
注意:SDK和程序路径最好不要有空格符
情况2:
Proguard returned with error code 1. See console
异常:
java.lang.ArrayIndexOutOfBoundsException
解决办法:将proguard.cfg中的"-dontpreverify"改成“-dontoptimize”
参考文章:http://groups.google.com/group/android-developers/browse_thread/thread/eca3b0f5ce6ad00f
我把项目中生成的proguard文件夹(此时文件夹是空的)删掉,然后再重新运行项目,就OK 了。
情况3:
[2011-10-21 13:22:32 - ZMKSMarket_Build_v1.0] Proguard returned with error code 1. See console
[2011-10-21 13:22:32 - ZMKSMarket_Build_v1.0] java.io.IOException: Can't read [proguard.ClassPathEntry@106082] (No such file or directory)
[2011-10-21 13:22:32 - ZMKSMarket_Build_v1.0] at proguard.InputReader.readInput(InputReader.java:230)
[2011-10-21 13:22:32 - ZMKSMarket_Build_v1.0] at proguard.InputReader.readInput(InputReader.java:200)
[2011-10-21 13:22:32 - ZMKSMarket_Build_v1.0] at proguard.InputReader.readInput(InputReader.java:178)
[2011-10-21 13:22:32 - ZMKSMarket_Build_v1.0] at proguard.InputReader.execute(InputReader.java:100)
[2011-10-21 13:22:32 - ZMKSMarket_Build_v1.0] at proguard.ProGuard.readInput(ProGuard.java:195)
[2011-10-21 13:22:32 - ZMKSMarket_Build_v1.0] at proguard.ProGuard.execute(ProGuard.java:78)
[2011-10-21 13:22:32 - ZMKSMarket_Build_v1.0] at proguard.ProGuard.main(ProGuard.java:499)
抛出这样的异常的原因是第三方jar的引用路径不对,没有找到这个需要忽略混淆的jar包。
参考:http://stackoverflow.com/questions/4884456/android-proguard-java-io-ioexception-cant-read-proguard-classpathentry
///*******************************************************************************************************************//////
- -optimizationpasses 5 //代码混淆压缩比 默认为5 一般不需要改 -dontusemixedcaseclassnames //混淆后的类名为小写 如public class a
- -dontskipnonpubliclibraryclasses //混淆第三方 库 加上此句后 可再后面配置某些库不混淆-dontpreverify // 混淆前认证,可去掉加快混淆速度
- -verbose //混淆的log 帮助排错
- -optimizations !code/simplification/arithmetic,!field/*,!class/merging/* //代码混淆采用的算法,一般不改变,用谷歌推荐算即可
- -keepattributes *Annotation* 假如项目中有用到注解 应用加入
- 引用外部的jar包 如果不是自己写的 最好不混淆它们,因为外部jar包有可能已经混淆过,根据实际情况来 不混淆某些外部jar
保持外部jar包不变的方法-dontwarn android.support.v4.** //执行下面一行代码如果有警告也不用中止,因为此jar不是我们自己写的,有警告也不处理,故dontwarn-keep class android.support.v4.** //项目中用到此jar包,在打包时必须不混淆,否则用ViewPager时必crash,原因很简单,ViewPager是一个自定义view,在布局中用类的全名来定义此布局,混淆后类名和包名改变,xml布局无法再通过类名打到此自定义view 如果你的项目中用到了webview的复杂操作 加入此两行代码
-keepclassmembers class * extends android.webkit.WebViewClient { public void *(android.webkit.WebView,java.lang.String,android.graphics.Bitmap); public boolean *(android.webkit.WebView,java.lang.String);}-keepclassmembers class * extends android.webkit.WebChromeClient { public void *(android.webkit.WebView,java.lang.String);}经过实战检验,做腾讯QQ登录,如果引用他们提供的jar,若不加防止WebChromeClient混淆的代码,oauth认证无法回调,反编译基代码后可看到他们有用到WebChromeClient,加入此代码即可,不过还是建议不要用他们提供的jar包做oauth认证,至于为啥,不解释正常开发 系统默认的混淆再加上以上基本的混淆即可满足,更多需求还需要去阅文档用到了anroid支持包加入-libraryjars libs/android-support-v4.jar-dontwarn android.support.v4.** -keep class android.support.v4.** { *; } -keep interface android.support.v4.app.** { *; } -keep public class * extends android.support.v4.** -keep public class * extends android.app.Fragment
来自:http://www.cnblogs.com/xxhong/archive/2013/01/22/2872330.html
/***********************************************************************************************************/
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标准,修改如下:
标准proguard.cfg文件内容
- XHTML
- # see http://sourceforge.net/tracker/?func=detail&aid=2787465&group_id=54750&atid=474707
- -optimizations !code/simplification/arithmetic
- -optimizations !code/simplification/cast
- -allowaccessmodification
- # To prevent name conflict in incremental obfuscation.
- -useuniqueclassmembernames
- # dex does not like code run through proguard optimize and preverify steps.
- -dontoptimize
- -dontpreverify
- # Don't obfuscate. We only need dead code striping.
- # -dontobfuscate
- # Add this flag in your package's own configuration if it's needed.
- #-flattenpackagehierarchy
- # Some classes in the libraries extend package private classes to chare common functionality
- # that isn't explicitly part of the API
- -dontskipnonpubliclibraryclasses -dontskipnonpubliclibraryclassmembers
- # For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations
- -keepclassmembers enum * {
- public static **[] values();
- public static ** valueOf(java.lang.String);
- }
- # For native methods, see http://proguard.sourceforge.net/manual/examples.html#native
- -keepclasseswithmembernames class * {
- native ;
- }
- # class$ methods are inserted by some compilers to implement .class construct,
- # see http://proguard.sourceforge.net/manual/examples.html#library
- -keepclassmembernames class * {
- java.lang.Class class$(java.lang.String);
- java.lang.Class class$(java.lang.String, boolean);
- }
- # Keep classes and methods that have the guava @VisibleForTesting annotation
- -keep @com.google.common.annotations.VisibleForTesting class *
- -keepclassmembers class * {
- @com.google.common.annotations.VisibleForTesting *;
- }
- # Keep serializable classes and necessary members for serializable classes
- # Copied from the ProGuard manual at http://proguard.sourceforge.net.
- -keepnames class * implements java.io.Serializable
- -keepclassmembers class * implements java.io.Serializable {
- static final long serialVersionUID;
- private static final java.io.ObjectStreamField[] serialPersistentFields;
- !static !transient ;
- private void writeObject(java.io.ObjectOutputStream);
- private void readObject(java.io.ObjectInputStream);
- java.lang.Object writeReplace();
- java.lang.Object readResolve();
- }
- # Please specify classes to be kept explicitly in your package's configuration.
- # -keep class * extends android.app.Activity
- # -keep class * extends android.view.View
- # -keep class * extends android.app.Service
- # -keep class * extends android.content.BroadcastReceiver
- # -keep class * extends android.content.ContentProvider
- # -keep class * extends android.preference.Preference
- # -keep class * extends android.app.BackupAgent
- -keep class * implements android.os.Parcelable {
- public static final android.os.Parcelable$Creator *;
- }
- # The support library contains references to newer platform versions.
- # Don't warn about those in case this app is linking against an older
- # platform version. We know about them, and they are safe.
- # See proguard-android.txt in the SDK package.
- -dontwarn android.support.**
- # see http://sourceforge.net/tracker/?func=detail&aid=2787465&group_id=54750&atid=474707
- -optimizations !code/simplification/arithmetic
- -optimizations !code/simplification/cast
- -allowaccessmodification
- # To prevent name conflict in incremental obfuscation.
- -useuniqueclassmembernames
- # dex does not like code run through proguard optimize and preverify steps.
- -dontoptimize
- -dontpreverify
- # Don't obfuscate. We only need dead code striping.
- # -dontobfuscate
- # Add this flag in your package's own configuration if it's needed.
- #-flattenpackagehierarchy
- # Some classes in the libraries extend package private classes to chare common functionality
- # that isn't explicitly part of the API
- -dontskipnonpubliclibraryclasses -dontskipnonpubliclibraryclassmembers
- # For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations
- -keepclassmembers enum * {
- public static **[] values();
- public static ** valueOf(java.lang.String);
- }
- # For native methods, see http://proguard.sourceforge.net/manual/examples.html#native
- -keepclasseswithmembernames class * {
- native ;
- }
- # class$ methods are inserted by some compilers to implement .class construct,
- # see http://proguard.sourceforge.net/manual/examples.html#library
- -keepclassmembernames class * {
- java.lang.Class class$(java.lang.String);
- java.lang.Class class$(java.lang.String, boolean);
- }
- # Keep classes and methods that have the guava @VisibleForTesting annotation
- -keep @com.google.common.annotations.VisibleForTesting class *
- -keepclassmembers class * {
- @com.google.common.annotations.VisibleForTesting *;
- }
- # Keep serializable classes and necessary members for serializable classes
- # Copied from the ProGuard manual at http://proguard.sourceforge.net.
- -keepnames class * implements java.io.Serializable
- -keepclassmembers class * implements java.io.Serializable {
- static final long serialVersionUID;
- private static final java.io.ObjectStreamField[] serialPersistentFields;
- !static !transient ;
- private void writeObject(java.io.ObjectOutputStream);
- private void readObject(java.io.ObjectInputStream);
- java.lang.Object writeReplace();
- java.lang.Object readResolve();
- }
- # Please specify classes to be kept explicitly in your package's configuration.
- # -keep class * extends android.app.Activity
- # -keep class * extends android.view.View
- # -keep class * extends android.app.Service
- # -keep class * extends android.content.BroadcastReceiver
- # -keep class * extends android.content.ContentProvider
- # -keep class * extends android.preference.Preference
- # -keep class * extends android.app.BackupAgent
- -keep class * implements android.os.Parcelable {
- public static final android.os.Parcelable$Creator *;
- }
- # The support library contains references to newer platform versions.
- # Don't warn about those in case this app is linking against an older
- # platform version. We know about them, and they are safe.
- # See proguard-android.txt in the SDK package.
- -dontwarn android.support.**
- 源文件见/build/core/proguard.flags , 将14行 -dontobfuscate解除注释。
3、常用proguard.cfg代码段
不混淆某类的构造方法,需指定构造函数的参数类型,如JSONObject
- Java
- -keepclassmembers class cn.trinea.android.common.service.impl.ImageCache {
- public (int);
- }
- 123-keepclassmembers class cn.trinea.android.common.service.impl.ImageCache {
- public (int);
- }
不混淆某个包所有类或某个类class、某个接口interface, 不混淆指定类则把**换成类名
- Java
- -keep class cn.trinea.android.common.** { *; }
- 1-keep class cn.trinea.android.common.** { *; }
不混淆指某个方法,*可换成指定的方法或类名
- Java
- -keepclassmembers class cn.trinea.android.common.service.impl.ImageCache {
- public boolean get(java.lang.String, android.view.View);
- }
- 123-keepclassmembers class cn.trinea.android.common.service.impl.ImageCache {
- public boolean get(java.lang.String, android.view.View);
- }
不混淆Parcelable的子类,防止android.os.BadParcelableException
- Java
- -keep class * implements android.os.Parcelable {
- public static final android.os.Parcelable$Creator *;
- }
- 123-keep class * implements android.os.Parcelable {
- public static final android.os.Parcelable$Creator *;
- }
添加android-support-v4.jar依赖包
- Java
- -libraryjars libs/android-support-v4.jar
- -dontwarn android.support.v4.**
- -keep class android.support.v4.** { *; }
- -keep interface android.support.v4.app.** { *; }
- 1234-libraryjars libs/android-support-v4.jar
- -dontwarn android.support.v4.**
- -keep class android.support.v4.** { *; }
- -keep interface android.support.v4.app.** { *; }
4、proguard与log level结合解决debug模式Log问题
常见的Android debug日志的打法是定义一个静态变量DEBUG_STATUS,如果为true,则打印log,否则不打印。对于release模式该变量为false,debug模式变量为true。这里介绍一个更好的方法,不用担心正式发布时一不小心错改了该变量。
proguard的作用就是在release模式压缩、优化、混淆代码,其中的压缩和优化就包括去除不必要的代码,我们可以利用这一特性解决debug日志的问题,在proguard.cfg中添加
- Java
- -assumenosideeffects class android.util.Log {
- public static *** d(...);
- public static *** v(...);
- }
- 1234-assumenosideeffects class android.util.Log {
- public static *** d(...);
- public static *** v(...);
- }
表示Log.d和Log.v代码无副作用,在proguard时会被从源码中remove掉,这样release模式(正式发布)就不会打印日志了,而debug模式(平常调试)照常打印,不用修改一点代码大赞吧,嘿嘿。
原文链接:http://www.trinea.cn/android/proguard%e8%af%ad%e6%b3%95%e5%8f%8a%e5%b8%b8%e7%94%a8proguard-cfg%e4%bb%a3%e7%a0%81%e6%ae%b5/
- proguard.cfg(转载)
- proguard.cfg
- proguard.cfg
- proguard.cfg
- Android 签名+混淆( 签名+proguard.cfg)
- 系统找不到proguard.cfg
- Proguard.cfg 配置
- 混淆的proguard.cfg
- proguard.cfg 配置文件
- 混淆打包proguard.cfg
- Proguard.cfg 配置
- Android- 关于proguard.cfg
- Android开发中正确删除Log的姿势(proguard.config=proguard.cfg)
- (方便自己查看)防反编译、混淆文件proguard.cfg与proguard-project.txt详解
- Eclipse找不到proguard.cfg解决办法
- Eclipse找不到proguard.cfg解决办法
- Android 混淆通用Proguard.cfg
- Hibernate.cfg.xml数据源配置(转载)
- Flex入门--Flex基本语法
- 串的简单处理
- 第一个小爬虫
- Palindrome Partitioning II
- android 用httpClient和HttpUrlConnection上传文件
- proguard.cfg(转载)
- ASPCMS多条件匹配搜索
- 列表编辑列下的“上移” “下移”操作
- 设置定时任务的技巧
- js之关键字和保留字
- 腾讯校园招聘会笔试题 难题解析
- hdu 1086 You can Solve a Geometry Problem too(计算几何水题)
- LR事务的四种状态
- Oracle数据库-建库、建表空间,建用户