一、 ProGuard是一个免费的Java类文件压缩、优化、混淆器和审核器,它检查并删除没有使用到的类、字段、方法和属性。它优化字节码并去除没有使用到的指令,它使用无意义的名字来重命名使用的类、字段和方法。它还验证代码。ProGuard可以用命令行、图形界面、Ant等来执行和处理程序。


         ProGuard不需要安装,只需要将ProGuard的解压到某目录下,然后配置下路径就OK啦,其实lib下面的3个Jar包就足够了。


       用命令行执行ProGuard的命令如下:



                java -jar proguard.jar @proguard.pro   其中proguard.pro文件中是指定的混淆配置信息。 



       

Ant方式运行ProGuard,只需要添加一个target即可: 
 
                 <target name="proguard" depends="init"> 
 
  
                      <taskdef resource="proguard/ant/task.properties"  classpath="${lib.dir}/proguard/proguard.jar" /> 
 
  
                      <proguard configuration="${src.dir}/config.pro" /> 
 
  
               </target>


 


       1). 什么是压缩: 



        Java 源代码(.java文件)通常被编译为字节码(.class文件)。而完整的程序或程序库通常被压缩和发布成Java文档(.jar文件)。字节码比 Java源文件更简洁,但是它仍然包含大量的无用代码,尤其它是一个程序库的时候。ProGuard的压缩程序操作能分析字节码,并删除无用的类、字段和方法。程序只保留功能上的等价,包括异常堆栈描述所需要的信息。 



       2). 什么是混淆: 



       通常情况下,编译后的字节码仍然包含了大量的调试信息:源文件名,行号,字段名,方法名,参数名,变量名等等。这些信息使得它很容易被反编译和通过逆向工程获得完整的程序。而像ProGuard这样的混淆器就能删除这些调试信息,并用无意义的字符序列来替换所有名字,使得它很难进行逆向工程,它进一步免费的精简代码。除了异常堆栈信息所需要的类名,方法名和行号外,程序只会保留功能上的等价。



 二、Proguard的作用:


       1.创建紧凑的代码文档,为了更快的网络传输,快速装载和更小的内存占用;



       2.创建的程序和程序库很难使用反向工程;



       3.能删除来自源文件中的没有调用的代码;



       4.充分利用java6的快速加载的优点来提前检测和返回java6中存在的类文件。



 三、Eclipse中的默认的proguard.cfg(存放在%android_dir%/tools/lib目录下)内容如下:


-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-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 *;
 } 
 
       
   Proguard的参数:
 
 
       -include {filename}    从给定的文件中读取配置参数 
 
  

 
  
       -basedirectory {directoryname}    指定基础目录为以后相对的档案名称 
 
  

 
  
       -injars {class_path}    指定要处理的应用程序jar,war,ear和目录 
 
  

 
  
       -outjars {class_path}    指定处理完后要输出的jar,war,ear和目录的名称 
 
  

 
  
       -libraryjars {classpath}    指定要处理的应用程序jar,war,ear和目录所需要的程序库文件 
 
  

 
  
       -dontskipnonpubliclibraryclasses    指定不忽略非公共的库类 
 
  

 
  
       -dontskipnonpubliclibraryclassmembers    指定不忽略包可见的库类的成员。 
 
  

 
  

 
  
        保留选项 
 
  
        -keep {Modifier} {class_specification}    保护指定的类文件和类的成员 
 
  

 
  
        -keepclassmembers {modifier} {class_specification}    保护指定类的成员,如果此类受到保护他们会保护的更好 
 
  

 
  
        -keepclasseswithmembers {class_specification}    保护指定的类和类的成员,指定的类和类成员必须是存在。 
 
  

 
  
        -keepnames {class_specification}    保护指定的类和类的成员的名称(如果他们不会压缩步骤中删除) 
 
  

 
  
        -keepclassmembernames {class_specification}    保护指定的类的成员的名称(如果他们不会压缩步骤中删除) 
 
  

 
  
        -keepclasseswithmembernames {class_specification}    保护指定的类和类的成员的名称,如果所有指定的类成员出席(在压缩步骤之后) 
 
  

 
  
        -printseeds {filename}    列出类和类的成员-keep选项的清单,标准输出到给定的文件 
 
  

 
  
         压缩 
 
  
         -dontshrink    不压缩输入的类文件 
 
  

 
  
         -printusage {filename} 
 
  

 
  
         -whyareyoukeeping {class_specification}     
 
  

 
  
         优化 
 
  
         -dontoptimize    不优化输入的类文件 
 
  

 
  
         -assumenosideeffects {class_specification}    优化时假设指定的方法,没有任何副作用 
 
  

 
  
         -allowaccessmodification    优化时允许访问并修改有修饰符的类和类的成员 
 
  

 
  
         混淆 
 
  
         -dontobfuscate    不混淆输入的类文件 
 
  

 
  
         -printmapping {filename} 
 
  

 
  
         -applymapping {filename}    重用映射增加混淆 
 
  

 
  
         -obfuscationdictionary {filename}    使用给定文件中的关键字作为要混淆方法的名称 
 
  

 
  
         -overloadaggressively    混淆时应用侵入式重载 
 
  

 
  
         -useuniqueclassmembernames    确定统一的混淆类的成员名称来增加混淆 
 
  

 
  
         -flattenpackagehierarchy {package_name}    重新包装所有重命名的包并放在给定的单一包中 
 
  

 
  
         -repackageclass {package_name}    重新包装所有重命名的类文件中放在给定的单一包中 
 
  

 
  
         -dontusemixedcaseclassnames    混淆时不会产生形形色色的类名 
 
  

 
  
         -keepattributes {attribute_name,...}    保护给定的可选属性,例如LineNumberTable, LocalVariableTable, SourceFile, Deprecated, Synthetic, Signature, and InnerClasses. 
 
  

 
  
          -renamesourcefileattribute {string}    设置源文件中给定的字符串常量 
 
  

 
  

 
  
        另外,不想继承某个类和实现某个接口的类被混淆:
 
  
         -keepclasseswithmembers class * { 
                public <init>(android.content.Context, android.util.AttributeSet); 
          } 
  
         -keepclasseswithmembers class * { 
                public <init>(android.content.Context, android.util.AttributeSet, int); 
         } 
  
        -keepclassmembers enum * { 
              public static **[] values(); 
              public static ** valueOf(java.lang.String); 
        } 
  
        -keep class * implements android.os.Parcelable { 
               public static final android.os.Parcelable$Creator *; 
        }