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。如下所示:

 1 # This file is automatically generated by Android Tools.
 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的一般情况进行了配置,我们打开这个配置文件。内容大概如下:

 1 -optimizationpasses 5
 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 


    它主要保留了继承自ActivityApplicationServiceBroadcastReceiverContentProviderBackupAgentHelperPreferenceILicensingService的子类。因为这些子类,都是可能被外部调用的。

另外,它还保留了含有native方法的类、构造函数从xml构造的类(一般为View的子类)、枚举类型中的valuesvalueOf静态方法、继承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的常用语法
 

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

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

  2、标准proguard.cfg文件内容

  参考android标准,修改如下:

  标准proguard.cfg文件内容
  
  1. XHTML
  2.   # see http://sourceforge.net/tracker/?func=detail&aid=2787465&group_id=54750&atid=474707
  3.   -optimizations !code/simplification/arithmetic
  4.   -optimizations !code/simplification/cast
  5.   -allowaccessmodification
  6.   # To prevent name conflict in incremental obfuscation.
  7.   -useuniqueclassmembernames
  8.   # dex does not like code run through proguard optimize and preverify steps.
  9.   -dontoptimize
  10.   -dontpreverify
  11.   # Don't obfuscate. We only need dead code striping.
  12.   # -dontobfuscate
  13.   # Add this flag in your package's own configuration if it's needed.
  14.   #-flattenpackagehierarchy
  15.   # Some classes in the libraries extend package private classes to chare common functionality
  16.   # that isn't explicitly part of the API
  17.   -dontskipnonpubliclibraryclasses -dontskipnonpubliclibraryclassmembers
  18.   # For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations
  19.   -keepclassmembers enum * {
  20.   public static **[] values();
  21.   public static ** valueOf(java.lang.String);
  22.   }
  23.   # For native methods, see http://proguard.sourceforge.net/manual/examples.html#native
  24.   -keepclasseswithmembernames class * {
  25.   native ;
  26.   }
  27.   # class$ methods are inserted by some compilers to implement .class construct,
  28.   # see http://proguard.sourceforge.net/manual/examples.html#library
  29.   -keepclassmembernames class * {
  30.   java.lang.Class class$(java.lang.String);
  31.   java.lang.Class class$(java.lang.String, boolean);
  32.   }
  33.   # Keep classes and methods that have the guava @VisibleForTesting annotation
  34.   -keep @com.google.common.annotations.VisibleForTesting class *
  35.   -keepclassmembers class * {
  36.   @com.google.common.annotations.VisibleForTesting *;
  37.   }
  38.   # Keep serializable classes and necessary members for serializable classes
  39.   # Copied from the ProGuard manual at http://proguard.sourceforge.net.
  40.   -keepnames class * implements java.io.Serializable
  41.   -keepclassmembers class * implements java.io.Serializable {
  42.   static final long serialVersionUID;
  43.   private static final java.io.ObjectStreamField[] serialPersistentFields;
  44.   !static !transient ;
  45.   private void writeObject(java.io.ObjectOutputStream);
  46.   private void readObject(java.io.ObjectInputStream);
  47.   java.lang.Object writeReplace();
  48.   java.lang.Object readResolve();
  49.   }
  50.   # Please specify classes to be kept explicitly in your package's configuration.
  51.   # -keep class * extends android.app.Activity
  52.   # -keep class * extends android.view.View
  53.   # -keep class * extends android.app.Service
  54.   # -keep class * extends android.content.BroadcastReceiver
  55.   # -keep class * extends android.content.ContentProvider
  56.   # -keep class * extends android.preference.Preference
  57.   # -keep class * extends android.app.BackupAgent
  58.   -keep class * implements android.os.Parcelable {
  59.   public static final android.os.Parcelable$Creator *;
  60.   }
  61.   # The support library contains references to newer platform versions.
  62.   # Don't warn about those in case this app is linking against an older
  63.   # platform version. We know about them, and they are safe.
  64.   # See proguard-android.txt in the SDK package.
  65.   -dontwarn android.support.**
  66.   # see http://sourceforge.net/tracker/?func=detail&aid=2787465&group_id=54750&atid=474707
  67.   -optimizations !code/simplification/arithmetic
  68.   -optimizations !code/simplification/cast
  69.   -allowaccessmodification
  70.   # To prevent name conflict in incremental obfuscation.
  71.   -useuniqueclassmembernames
  72.   # dex does not like code run through proguard optimize and preverify steps.
  73.   -dontoptimize
  74.   -dontpreverify
  75.   # Don't obfuscate. We only need dead code striping.
  76.   # -dontobfuscate
  77.   # Add this flag in your package's own configuration if it's needed.
  78.   #-flattenpackagehierarchy
  79.   # Some classes in the libraries extend package private classes to chare common functionality
  80.   # that isn't explicitly part of the API
  81.   -dontskipnonpubliclibraryclasses -dontskipnonpubliclibraryclassmembers
  82.   # For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations
  83.   -keepclassmembers enum * {
  84.   public static **[] values();
  85.   public static ** valueOf(java.lang.String);
  86.   }
  87.   # For native methods, see http://proguard.sourceforge.net/manual/examples.html#native
  88.   -keepclasseswithmembernames class * {
  89.   native ;
  90.   }
  91.   # class$ methods are inserted by some compilers to implement .class construct,
  92.   # see http://proguard.sourceforge.net/manual/examples.html#library
  93.   -keepclassmembernames class * {
  94.   java.lang.Class class$(java.lang.String);
  95.   java.lang.Class class$(java.lang.String, boolean);
  96.   }
  97.   # Keep classes and methods that have the guava @VisibleForTesting annotation
  98.   -keep @com.google.common.annotations.VisibleForTesting class *
  99.   -keepclassmembers class * {
  100.   @com.google.common.annotations.VisibleForTesting *;
  101.   }
  102.   # Keep serializable classes and necessary members for serializable classes
  103.   # Copied from the ProGuard manual at http://proguard.sourceforge.net.
  104.   -keepnames class * implements java.io.Serializable
  105.   -keepclassmembers class * implements java.io.Serializable {
  106.   static final long serialVersionUID;
  107.   private static final java.io.ObjectStreamField[] serialPersistentFields;
  108.   !static !transient ;
  109.   private void writeObject(java.io.ObjectOutputStream);
  110.   private void readObject(java.io.ObjectInputStream);
  111.   java.lang.Object writeReplace();
  112.   java.lang.Object readResolve();
  113.   }
  114.   # Please specify classes to be kept explicitly in your package's configuration.
  115.   # -keep class * extends android.app.Activity
  116.   # -keep class * extends android.view.View
  117.   # -keep class * extends android.app.Service
  118.   # -keep class * extends android.content.BroadcastReceiver
  119.   # -keep class * extends android.content.ContentProvider
  120.   # -keep class * extends android.preference.Preference
  121.   # -keep class * extends android.app.BackupAgent
  122.   -keep class * implements android.os.Parcelable {
  123.   public static final android.os.Parcelable$Creator *;
  124.   }
  125.   # The support library contains references to newer platform versions.
  126.   # Don't warn about those in case this app is linking against an older
  127.   # platform version. We know about them, and they are safe.
  128.   # See proguard-android.txt in the SDK package.
  129.   -dontwarn android.support.**
  130.   源文件见/build/core/proguard.flags , 将14行 -dontobfuscate解除注释。
复制代码

  3、常用proguard.cfg代码段

  不混淆某类的构造方法,需指定构造函数的参数类型,如JSONObject
  
  1. Java
  2.   -keepclassmembers class cn.trinea.android.common.service.impl.ImageCache {
  3.   public (int);
  4.   }
  5.   123-keepclassmembers class cn.trinea.android.common.service.impl.ImageCache {
  6.   public (int);
  7.   }
复制代码

  不混淆某个包所有类或某个类class、某个接口interface, 不混淆指定类则把**换成类名
  
  1. Java
  2.   -keep class cn.trinea.android.common.** { *; }
  3.   1-keep class cn.trinea.android.common.** { *; }
复制代码

  不混淆指某个方法,*可换成指定的方法或类名
 
  1.  Java
  2.   -keepclassmembers class cn.trinea.android.common.service.impl.ImageCache {
  3.   public boolean get(java.lang.String, android.view.View);
  4.   }
  5.   123-keepclassmembers class cn.trinea.android.common.service.impl.ImageCache {
  6.   public boolean get(java.lang.String, android.view.View);
  7.   }
复制代码

  不混淆Parcelable的子类,防止android.os.BadParcelableException
  
  1. Java
  2.   -keep class * implements android.os.Parcelable {
  3.   public static final android.os.Parcelable$Creator *;
  4.   }
  5.   123-keep class * implements android.os.Parcelable {
  6.   public static final android.os.Parcelable$Creator *;
  7.   }
复制代码

  添加android-support-v4.jar依赖包
  
  1. Java
  2.   -libraryjars libs/android-support-v4.jar
  3.   -dontwarn android.support.v4.**
  4.   -keep class android.support.v4.** { *; }
  5.   -keep interface android.support.v4.app.** { *; }
  6.   1234-libraryjars libs/android-support-v4.jar
  7.   -dontwarn android.support.v4.**
  8.   -keep class android.support.v4.** { *; }
  9.   -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中添加
  
  1. Java
  2.   -assumenosideeffects class android.util.Log {
  3.   public static *** d(...);
  4.   public static *** v(...);
  5.   }
  6.   1234-assumenosideeffects class android.util.Log {
  7.   public static *** d(...);
  8.   public static *** v(...);
  9.   }
复制代码

  表示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/


0 0
原创粉丝点击