Android 代码混淆选项详细说明

转载 2016年05月31日 14:51:14


Input/Output Options   输入/输出 选项

@filename  
Short for '-include filename'.
-include filename  
递归读取目录中(如果有)文件的 配置:configuration options
-basedirectory directoryname
配置文件的目录   directoryname规则见filename
-injars class_path
输入(即使用的) jar文件路径

        例:-injars "my program.jar":"/your directory/your program.jar"引号可以不要
-outjars class_path
输出 jar 路径
-libraryjars class_path
指定的jar将不被混淆,just run-time jar
-skipnonpubliclibraryclasses
跳过(不混淆) jars中的 非public classes 
-dontskipnonpubliclibraryclasses
不跳过(混淆) jars中的 非public classes   默认选项
-dontskipnonpubliclibraryclassmembers
不跳过 jars中的非public classes的members
-keepdirectories [directory_filter]
指定目录 keep 在 out jars中    directory_filter规则见file filter
-target version
Java版本  1.0, 1.1, 1.2, 1.3, 1.4, 1.5 (or just 5), 1.6 (or just 6), or 1.7 (or just 7).
-forceprocessing
指定input处理,即使output seems up to date


Keep Options  保持不变的选项

-keep [,modifier,...] class_specification

保持class_specification规则若有[,modifier,...],则先启用它的规则

-keepclassmembers [,modifier,...]class_specification

保持类的成员:属性(可以是成员属性、类属性)、方法(可以是成员方法、类方法)

-keepclasseswithmembers [,modifier,...] class_specification

与-keep功能基本一致(经测试)

-keepnames class_specification
Short for -keep,allowshrinking class_specification

-keepclassmembernames class_specification
Short for -keepclassmembers,allowshrinking class_specification

-keepclasseswithmembernames class_specification
Short for -keepclasseswithmembers,allowshrinking class_specification

-printseeds [filename]

打印匹配的-keep家族处理的 类和类成员列表,到标准输出。

用Proguard 命令行,能看到输出效果(未测试)


Shrinking Options 压缩选项

shrink,测试后发现会将一些无效代码给移除,即没有被显示调用的代码

-dontshrink

shrink操作默认启用,每个optimization步骤后,都会执行一步shrink。

该选项 表示 不启用 shrink。

测试后发现是全局性的,且即便使用了-keep 开启shrink,也无效

-printusage [filename]

打印被移除的代码,在标准输出
-whyareyoukeeping class_specification

打印 在shrink过程中 为什么有些代码被 keep


Optimization Options 优化选项

基于控制流、数据流分析后,删除、合并一些代码
-dontoptimize

optimization,默认启用

该选项表示 不启用

当不使用该选项时,下面的才有效
-optimizations optimization_filter

根据optimization_filter指定要优化的文件
-optimizationpasses n

优化数量 n  
-assumenosideeffects class_specification

如果一个方法有返回值,在调用的时候没使用到它的返回值,那么可能被忽略。

-allowaccessmodification

优化时允许访问并修改类和类的成员的 访问修饰符,可能作用域会变大。
-mergeinterfacesaggressively

竭力合并接口,即使它们的实现类未实现合并后接口的所有方法。


Obfuscation Options 混淆选项

混淆类名、属性名、方法名、变量名等,变成无意义的类似a,b,c,d...的名字

-dontobfuscate
不混淆
-printmapping [filename]
打印 映射旧名到新名
-applymapping filename
打印相关
-obfuscationdictionary filename
指定外部模糊字典
-classobfuscationdictionary filename
指定class模糊字典
-packageobfuscationdictionary filename
指定package模糊字典
-overloadaggressively
过度加载,多个属性和方法使用相同的名字,只是参数和返回类型不同 可能各种异常
-useuniqueclassmembernames
类和类成员都使用唯一的名字
-dontusemixedcaseclassnames
不使用大小写混合类名
-keeppackagenames [package_filter]
保持packagename 不混淆
-flattenpackagehierarchy [package_name]
指定重新打包,所有包重命名,这个选项会进一步模糊包名 好东西
将包里的类混淆成n个再重新打包到一个个的package中
-repackageclasses [package_name]
将包里的类混淆成n个再重新打包到一个统一的package中  会覆盖flattenpackagehierarchy选项
-keepattributes [attribute_filter]
# 混淆时可能被移除下面这些东西,如果想保留,需要用该选项。对于一般注解处理如 -keepattributes *Annotation*
# attribute_filter : Exceptions, Signature, Deprecated, SourceFile, SourceDir, LineNumberTable,
#LocalVariableTable, LocalVariableTypeTable, Synthetic,
#EnclosingMethod, RuntimeVisibleAnnotations, RuntimeInvisibleAnnotations, RuntimeVisibleParameterAnnotations,
#RuntimeInvisibleParameterAnnotations, and AnnotationDefault.

-keepparameternames

-renamesourcefileattribute [string]

-adaptclassstrings [class_filter]

-adaptresourcefilenames [file_filter]

-adaptresourcefilecontents [file_filter]


Preverification Options 预校验选项

-dontpreverify
-microedition


General Options 通用选项

-verbose

打印详细
-dontnote [class_filter]

不打印某些错误
-dontwarn [class_filter]

不打印警告信息
-ignorewarnings

忽略警告,继续执行
-printconfiguration [filename]

打印配置文件
-dump [filename]

指定打印类结构


其他说明

Class Paths : class_path

类路径,unix分隔符为冒号(:),windows分隔符为分号(;)
可以表示的文件类型有:
· a class file or resource file
· a jar file
· a war file
· an ear file
· a zip file
· a directory(structure)

File Names : filename

文件或目录名,可以使用相对或绝对路径
可以使用Java system properties,表示法:<...>
如:<java.home>、<user.home>、<user.dir> 等

File Filters : file_filter

文件过滤。
通配符:
?  匹配任意一个单个字符
*  匹配任意多个字符,不含目录分隔符:unix下为(/),windows下为(\)
** 匹配任意多个字符,含目录分隔符
还可以使用一个逻辑符号:!
! 表示 求反,除...之外

Filters : package_filter、attribute_filter、class_filter

可以过滤的有:names of files, directories, classes, packages, attributes, optimizations(见下文)
通配符:
?  匹配任意一个单个字符
*  匹配任意多个字符,不含目录分隔符和package分隔符:. 
** 匹配任意多个字符,含目录分隔符和package分隔符:. 
还可以使用一个逻辑符号:!
! 表示 求反,除...之外

Overview of Keep Options 

keep 选项,表示保持 类或类成员(方法和属性) 不变。各选项间的关系:

Keep

(保护、保持)

From being removed or renamed

(保护 将会删除或重命名)

From being renamed

(保护 将重命名)

Classes and class members

-keep

-keepnames

Class members only

-keepclassmembers

-keepclassmembernames

Classes and class members, if class members present

-keepclasseswithmembers

-keepclasseswithmembernames

每个keep选项 后面都跟一个 class_specification 
注意:
· 只指定class时,那么类的成员还是可以被移除、优化、混淆
· 指定了类的某些成员时,那么除这些之外的其它的成员 还是可以被 移除、优化、混淆

Keep Option Modifiers : modifiers

 allowshrinking    启用压缩

压缩默认启用

如果 上一条keep 了(即不压缩),而下一条allowshrinking,则还是会压缩,即:会覆盖上面的配置
 allowoptimization启用优化

优化默认启用

会覆盖上面的配置
 allowobfuscation启用混淆

混淆默认启用

会覆盖上面的配置

例:

-keep public class com.stone.*Activity    保护任意com.stone包下的*Activity

-keep ,allowshrinking public class com.stone.*Activity  启用压缩    


Class Specifications  类规范

完整语法
[@annotationtype] [[!]public|final|abstract|@...] [!]interface|class|enumclassname [extends|implements [@annotationtype]classname]
[{
    [
@annotationtype] [[!]public|private|protected|static|volatile|transient...]<fields> | (fieldtype fieldname);
    [
@annotationtype] [[!]public|private|protected|static|synchronized|native|abstract
          |strictfp ...]<methods> |<init>(argumenttype,...) |classname(argumenttype,...) |(returntype methodname(argumenttype,...));
    [@annotationtype] [[!]public|private|protected|static ... ] *;                                                
    
...
}]
蓝色的java关键字
[ ] 表示里面的内容是可选的。  
@ 表示是一个注解类型  annotationtype的规范与classname类似
...
    [[!]public|final|abstract|@ ...] : ...表示可以写上前面选项中的任意一种或多种。不参与语法
    (argumenttype,...)  :... 参与语法,表示0个或多个任意参数类型
| 表示或
! 表示非 
()在表示方法时,才是语法的一部份;其它时候,只是用来分组
classname 需要使用完全限定类名(即含包名的类名)
    可以使用如下通配符匹配类名:
      ? 匹配一个任意字符
      *  匹配多个任意字符,不含package分隔符.
     ** 匹配多个任意字符,含package分隔符.

属性(fields)和方法(methods):
   它们的规范与java中的规范类似,只是方法中不需要写上参数名,有参数类型即可
   <init>  matches any constructor.  
   <fields>  matches any field.
   <methods>  matches any method.
   * matches any field or method.   注意这四个通配符,本身不含 访问修饰符
   属性或方法后面都要以分号(;)结尾
   属性名或方法名可以使用的通配符:
       ?匹配任意一个字符
       *  匹配任意多个字符
   属性或方法类型(类型可以直接写,如果是一个class,则写上class的完全限定名)可以使用的通配符:
       %  表示任意基本数据类型,不含void
       ?   表示匹配用作类型的 class name的任意一个字符
       *    任意多个字符,不含package分隔符(.)
       **   任意多个字符,含package分隔符(.)    匹配非基本数据类型和非数组类型
             例:  ** get*()  可匹配com.stone.User getCurUser(),
               但不匹配String getName(),也不匹配com.stone.User[ ] getCurUser()。
       ***  匹配任意类型
       ...   表示任意数量的任意参数类型
  构造方法中的class name,可以用短类名或含包名的类名
 

 Optimizations : optimization_filter

当不使用-dontobfuscate选项时,则-optimizationsoptimization_filter才有效

optimization_filter 可以使用的通配符:

  ?任意一个字符 (没啥用)

  *  任意多个字符

可以用 ! 表示 非

For example, "code/simplification/variable,code/simplification/arithmetic" only performs the two specified peephole optimizations.

For example, "!method/propagation/*" performs all optimizations, except the ones that propagate values between methods.

For example, "!code/simplification/advanced,code/simplification/*" only performs all peephole optimizations.


optimization_filter 表示的有:

class/marking/final
Marks classes as final, whenever possible.

在任何可能的时候,将类标志为final class
class/merging/vertical
Merges classes vertically in the class hierarchy, whenever possible.

垂直合并类(上下层级的类 进行合并)
class/merging/horizontal
Merges classes horizontally in the class hierarchy, whenever possible.

水平合并类(同一层级的类 进行合并)
(⇒ code/removal/advanced)   表示当前选项是=>后的  前置选项

field/removal/writeonly
Removes write-only fields.

删除只写 属性
field/marking/private
Marks fields as private, whenever possible.

标记属性为private
(⇒ code/simplification/advanced)

field/propagation/value
Propagates the values of fields across methods.

在方法中传播属性值
method/marking/private
Marks methods as private, whenever possible (devirtualization).

标记属性为private(具体化)
(⇒ code/removal/advanced)

method/marking/static
Marks methods as static, whenever possible (devirtualization).

标记方法为static(具体化)
method/marking/final
Marks methods as final, whenever possible.

标记方法为final
(⇒ code/removal/advanced)

method/removal/parameter
Removes unused method parameters.

删除未使用的方法参数
(⇒ code/simplification/advanced)

method/propagation/parameter
Propagates the values of method parameters from method invocations to the invoked methods.

从方法的invocations传递方法参数值到 实际调用方法的地方invoked methods
(⇒ code/simplification/advanced)

method/propagation/returnvalue
Propagates the values of method return values from methods to their invocations.

传递方法的返回值 从方法到它们被调用的地方
method/inlining/short
Inlines short methods.

内联短方法
method/inlining/unique
Inlines methods that are only called once.

内联 仅被调用一次(或者说只被一个地方调用)的短方法
method/inlining/tailrecursion
Simplifies tail recursion calls, whenever possible.

简化尾递归 (尾递归转循环)
code/merging
Merges identical blocks of code by modifying branch targets.

合并相同的代码块
code/simplification/variable
Performs peephole optimizations for variable loading and storing.

变量加载和存储时 使用peephole optimization(窥孔优化)技术
code/simplification/arithmetic
Performs peephole optimizations for arithmetic instructions.

计算指令 用 窥孔优化
code/simplification/cast
Performs peephole optimizations for casting operations.

类型转换 用 窥孔优化
code/simplification/field
Performs peephole optimizations for field loading and storing.

属性加载和存储 用 窥孔优化
(⇒ code/removal/simple)

code/simplification/branch
Performs peephole optimizations for branch instructions.

分支指令 用 窥孔优化
code/simplification/string
Performs peephole optimizations for constant strings.

常量字符串 用 窥孔优化
(best used with code/removal/advanced)

code/simplification/advanced
Simplifies code based on control flow analysis and data flow analysis.

简化代码 基于控制流分析和数据流分析 
(⇒ code/removal/exception)

code/removal/advanced
Removes dead code based on control flow analysis and data flow analysis.

删除死代码 基于控制流分析和数据流分析
(⇒ code/removal/exception)

code/removal/simple
Removes dead code based on a simple control flow analysis.

删除死代码 基于一个简单的控制流分析
code/removal/variable
Removes unused variables from the local variable frame.

从本地变量框架中,删除 未使用的变量
code/removal/exception
Removes exceptions with empty try blocks.

当try-catch中,try块内为空时,删除exceptions
code/allocation/variable
Optimizes variable allocation on the local variable frame.

在本地变量框架中 优化变量分配

注意

· 上一句保护,下一句启用modifers, 启用无效; 上一句启用modifiers,下一句保护,保护有效。 重在保护

· 使用了-dontshrink|dontoptimize|dontobfuscate 这些全局选项后,那么再使用相应的kepp modifiers 无效

· 当不使用-dontoptimize选项时,则-optimizations optimization_filter才有效

· 测试发现jdk中就有优化不通过的地方,并且这个优化时间很长时间,还可能造成优化程序不结束(一直在运行,结束不了)

   所以一般还是直接使用 -dontoptimize。sdk中的proguard的配置文件也是这么写的。如果你想专业点,自行调试吧~


示例

[plain] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. -dontoptimize  #不优化  
  2. -dontpreverify #不预校验  
  3.   
  4. #保持源文件和行号的信息,用于混淆后定位错误位置  
  5. -keepattributes SourceFile,LineNumberTable  
  6.   
  7. -libraryjars class_path  #不处理 class_path指定的文件  
  8.   
  9. -dontusemixedcaseclassnames  #不使用大小写混合类名  
  10. -dontskipnonpubliclibraryclasses #不跳过jars中的非public classes。在proguard4.5时,是默认选项  
  11. -verbose  
  12.   
  13. -flattenpackagehierarchy com.stone.myapplication.interfaces # 将包里的类混淆成n个再重新打包到一个一个的package中  
  14. -repackageclasses com.stone.myapplication.interfaces #将包里的类混淆成n个再重新打包到一个统一的package中 会覆盖flattenpackagehierarchy选项  
  15.   
  16. -keepattributes *Annotation* #保持含有Annotation字符串的 attributes  
  17. -keep public class com.google.vending.licensing.ILicensingService  
  18. -keep public class com.android.vending.licensing.ILicensingService  
  19.   
  20. #保持 本化方法及其类声明  
  21. -keepclasseswithmembernames class * {   
  22.     native <methods>;  
  23. }  
  24. #保持view的子类成员: getter setter  
  25. -keepclassmembers public class * extends android.view.View {   
  26.    void set*(***);  
  27.    *** get*();  
  28. }  
  29. #保持Activity的子类成员:参数为一个View类型的方法   如setContentView(View v)  
  30. -keepclassmembers class * extends android.app.Activity {  
  31.    public void *(android.view.View);  
  32. }  
  33. #保持枚举类的成员:values方法和valueOf  (每个enum 类都默认有这两个方法)  
  34. -keepclassmembers enum * {  
  35.     public static **[] values();  
  36.     public static ** valueOf(java.lang.String);  
  37. }  
  38. #保持Parcelable的实现类和它的成员:类型为android.os.Parcelable$Creator 名字任意的 属性  
  39. -keep class * implements android.os.Parcelable {  
  40.   public static final android.os.Parcelable$Creator *;  
  41. }  
  42. #保持 任意包名.R类的类成员属性。  即保护R文件中的属性名不变  
  43. -keepclassmembers class **.R$* {  
  44.     public static <fields>;  
  45. }  
  46. #不警告 support包  
  47. -dontwarn android.support.**  
  48.   
  49. -keepattributes Signature   #保持签名  
  50. #下面三个gson相关  
  51. -keep class sun.misc.Unsafe {*;}  
  52. -keep class com.google.gson.examples.android.model.**{*;}  
  53. -keep class com.tv.kuaisou.bean.* {*;}  
  54.   
  55. -keep public class * extends android.app.Activity  
  56. -keep public class * extends android.app.Application  
  57. -keep public class * extends android.app.Service  
  58. -keep public class * extends android.content.BroadcastReceiver  
  59. -keep public class * extends android.content.ContentProvider  

Input/Output Options   输入/输出 选项

@filename  
Short for '-include filename'.
-include filename  
递归读取目录中(如果有)文件的 配置:configuration options
-basedirectory directoryname
配置文件的目录   directoryname规则见filename
-injars class_path
输入(即使用的) jar文件路径

        例:-injars "my program.jar":"/your directory/your program.jar"引号可以不要
-outjars class_path
输出 jar 路径
-libraryjars class_path
指定的jar将不被混淆,just run-time jar
-skipnonpubliclibraryclasses
跳过(不混淆) jars中的 非public classes 
-dontskipnonpubliclibraryclasses
不跳过(混淆) jars中的 非public classes   默认选项
-dontskipnonpubliclibraryclassmembers
不跳过 jars中的非public classes的members
-keepdirectories [directory_filter]
指定目录 keep 在 out jars中    directory_filter规则见file filter
-target version
Java版本  1.0, 1.1, 1.2, 1.3, 1.4, 1.5 (or just 5), 1.6 (or just 6), or 1.7 (or just 7).
-forceprocessing
指定input处理,即使output seems up to date


Keep Options  保持不变的选项

-keep [,modifier,...] class_specification

保持class_specification规则若有[,modifier,...],则先启用它的规则

-keepclassmembers [,modifier,...]class_specification

保持类的成员:属性(可以是成员属性、类属性)、方法(可以是成员方法、类方法)

-keepclasseswithmembers [,modifier,...] class_specification

与-keep功能基本一致(经测试)

-keepnames class_specification
Short for -keep,allowshrinking class_specification

-keepclassmembernames class_specification
Short for -keepclassmembers,allowshrinking class_specification

-keepclasseswithmembernames class_specification
Short for -keepclasseswithmembers,allowshrinking class_specification

-printseeds [filename]

打印匹配的-keep家族处理的 类和类成员列表,到标准输出。

用Proguard 命令行,能看到输出效果(未测试)


Shrinking Options 压缩选项

shrink,测试后发现会将一些无效代码给移除,即没有被显示调用的代码

-dontshrink

shrink操作默认启用,每个optimization步骤后,都会执行一步shrink。

该选项 表示 不启用 shrink。

测试后发现是全局性的,且即便使用了-keep 开启shrink,也无效

-printusage [filename]

打印被移除的代码,在标准输出
-whyareyoukeeping class_specification

打印 在shrink过程中 为什么有些代码被 keep


Optimization Options 优化选项

基于控制流、数据流分析后,删除、合并一些代码
-dontoptimize

optimization,默认启用

该选项表示 不启用

当不使用该选项时,下面的才有效
-optimizations optimization_filter

根据optimization_filter指定要优化的文件
-optimizationpasses n

优化数量 n  
-assumenosideeffects class_specification

如果一个方法有返回值,在调用的时候没使用到它的返回值,那么可能被忽略。

-allowaccessmodification

优化时允许访问并修改类和类的成员的 访问修饰符,可能作用域会变大。
-mergeinterfacesaggressively

竭力合并接口,即使它们的实现类未实现合并后接口的所有方法。


Obfuscation Options 混淆选项

混淆类名、属性名、方法名、变量名等,变成无意义的类似a,b,c,d...的名字

-dontobfuscate
不混淆
-printmapping [filename]
打印 映射旧名到新名
-applymapping filename
打印相关
-obfuscationdictionary filename
指定外部模糊字典
-classobfuscationdictionary filename
指定class模糊字典
-packageobfuscationdictionary filename
指定package模糊字典
-overloadaggressively
过度加载,多个属性和方法使用相同的名字,只是参数和返回类型不同 可能各种异常
-useuniqueclassmembernames
类和类成员都使用唯一的名字
-dontusemixedcaseclassnames
不使用大小写混合类名
-keeppackagenames [package_filter]
保持packagename 不混淆
-flattenpackagehierarchy [package_name]
指定重新打包,所有包重命名,这个选项会进一步模糊包名 好东西
将包里的类混淆成n个再重新打包到一个个的package中
-repackageclasses [package_name]
将包里的类混淆成n个再重新打包到一个统一的package中  会覆盖flattenpackagehierarchy选项
-keepattributes [attribute_filter]
# 混淆时可能被移除下面这些东西,如果想保留,需要用该选项。对于一般注解处理如 -keepattributes *Annotation*
# attribute_filter : Exceptions, Signature, Deprecated, SourceFile, SourceDir, LineNumberTable,
#LocalVariableTable, LocalVariableTypeTable, Synthetic,
#EnclosingMethod, RuntimeVisibleAnnotations, RuntimeInvisibleAnnotations, RuntimeVisibleParameterAnnotations,
#RuntimeInvisibleParameterAnnotations, and AnnotationDefault.

-keepparameternames

-renamesourcefileattribute [string]

-adaptclassstrings [class_filter]

-adaptresourcefilenames [file_filter]

-adaptresourcefilecontents [file_filter]


Preverification Options 预校验选项

-dontpreverify
-microedition


General Options 通用选项

-verbose

打印详细
-dontnote [class_filter]

不打印某些错误
-dontwarn [class_filter]

不打印警告信息
-ignorewarnings

忽略警告,继续执行
-printconfiguration [filename]

打印配置文件
-dump [filename]

指定打印类结构


其他说明

Class Paths : class_path

类路径,unix分隔符为冒号(:),windows分隔符为分号(;)
可以表示的文件类型有:
· a class file or resource file
· a jar file
· a war file
· an ear file
· a zip file
· a directory(structure)

File Names : filename

文件或目录名,可以使用相对或绝对路径
可以使用Java system properties,表示法:<...>
如:<java.home>、<user.home>、<user.dir> 等

File Filters : file_filter

文件过滤。
通配符:
?  匹配任意一个单个字符
*  匹配任意多个字符,不含目录分隔符:unix下为(/),windows下为(\)
** 匹配任意多个字符,含目录分隔符
还可以使用一个逻辑符号:!
! 表示 求反,除...之外

Filters : package_filter、attribute_filter、class_filter

可以过滤的有:names of files, directories, classes, packages, attributes, optimizations(见下文)
通配符:
?  匹配任意一个单个字符
*  匹配任意多个字符,不含目录分隔符和package分隔符:. 
** 匹配任意多个字符,含目录分隔符和package分隔符:. 
还可以使用一个逻辑符号:!
! 表示 求反,除...之外

Overview of Keep Options 

keep 选项,表示保持 类或类成员(方法和属性) 不变。各选项间的关系:

Keep

(保护、保持)

From being removed or renamed

(保护 将会删除或重命名)

From being renamed

(保护 将重命名)

Classes and class members

-keep

-keepnames

Class members only

-keepclassmembers

-keepclassmembernames

Classes and class members, if class members present

-keepclasseswithmembers

-keepclasseswithmembernames

每个keep选项 后面都跟一个 class_specification 
注意:
· 只指定class时,那么类的成员还是可以被移除、优化、混淆
· 指定了类的某些成员时,那么除这些之外的其它的成员 还是可以被 移除、优化、混淆

Keep Option Modifiers : modifiers

 allowshrinking    启用压缩

压缩默认启用

如果 上一条keep 了(即不压缩),而下一条allowshrinking,则还是会压缩,即:会覆盖上面的配置
 allowoptimization启用优化

优化默认启用

会覆盖上面的配置
 allowobfuscation启用混淆

混淆默认启用

会覆盖上面的配置

例:

-keep public class com.stone.*Activity    保护任意com.stone包下的*Activity

-keep ,allowshrinking public class com.stone.*Activity  启用压缩    


Class Specifications  类规范

完整语法
[@annotationtype] [[!]public|final|abstract|@...] [!]interface|class|enumclassname [extends|implements [@annotationtype]classname]
[{
    [
@annotationtype] [[!]public|private|protected|static|volatile|transient...]<fields> | (fieldtype fieldname);
    [
@annotationtype] [[!]public|private|protected|static|synchronized|native|abstract
          |strictfp ...]<methods> |<init>(argumenttype,...) |classname(argumenttype,...) |(returntype methodname(argumenttype,...));
    [@annotationtype] [[!]public|private|protected|static ... ] *;                                                
    
...
}]
蓝色的java关键字
[ ] 表示里面的内容是可选的。  
@ 表示是一个注解类型  annotationtype的规范与classname类似
...
    [[!]public|final|abstract|@ ...] : ...表示可以写上前面选项中的任意一种或多种。不参与语法
    (argumenttype,...)  :... 参与语法,表示0个或多个任意参数类型
| 表示或
! 表示非 
()在表示方法时,才是语法的一部份;其它时候,只是用来分组
classname 需要使用完全限定类名(即含包名的类名)
    可以使用如下通配符匹配类名:
      ? 匹配一个任意字符
      *  匹配多个任意字符,不含package分隔符.
     ** 匹配多个任意字符,含package分隔符.

属性(fields)和方法(methods):
   它们的规范与java中的规范类似,只是方法中不需要写上参数名,有参数类型即可
   <init>  matches any constructor.  
   <fields>  matches any field.
   <methods>  matches any method.
   * matches any field or method.   注意这四个通配符,本身不含 访问修饰符
   属性或方法后面都要以分号(;)结尾
   属性名或方法名可以使用的通配符:
       ?匹配任意一个字符
       *  匹配任意多个字符
   属性或方法类型(类型可以直接写,如果是一个class,则写上class的完全限定名)可以使用的通配符:
       %  表示任意基本数据类型,不含void
       ?   表示匹配用作类型的 class name的任意一个字符
       *    任意多个字符,不含package分隔符(.)
       **   任意多个字符,含package分隔符(.)    匹配非基本数据类型和非数组类型
             例:  ** get*()  可匹配com.stone.User getCurUser(),
               但不匹配String getName(),也不匹配com.stone.User[ ] getCurUser()。
       ***  匹配任意类型
       ...   表示任意数量的任意参数类型
  构造方法中的class name,可以用短类名或含包名的类名
 

 Optimizations : optimization_filter

当不使用-dontobfuscate选项时,则-optimizationsoptimization_filter才有效

optimization_filter 可以使用的通配符:

  ?任意一个字符 (没啥用)

  *  任意多个字符

可以用 ! 表示 非

For example, "code/simplification/variable,code/simplification/arithmetic" only performs the two specified peephole optimizations.

For example, "!method/propagation/*" performs all optimizations, except the ones that propagate values between methods.

For example, "!code/simplification/advanced,code/simplification/*" only performs all peephole optimizations.


optimization_filter 表示的有:

class/marking/final
Marks classes as final, whenever possible.

在任何可能的时候,将类标志为final class
class/merging/vertical
Merges classes vertically in the class hierarchy, whenever possible.

垂直合并类(上下层级的类 进行合并)
class/merging/horizontal
Merges classes horizontally in the class hierarchy, whenever possible.

水平合并类(同一层级的类 进行合并)
(⇒ code/removal/advanced)   表示当前选项是=>后的  前置选项

field/removal/writeonly
Removes write-only fields.

删除只写 属性
field/marking/private
Marks fields as private, whenever possible.

标记属性为private
(⇒ code/simplification/advanced)

field/propagation/value
Propagates the values of fields across methods.

在方法中传播属性值
method/marking/private
Marks methods as private, whenever possible (devirtualization).

标记属性为private(具体化)
(⇒ code/removal/advanced)

method/marking/static
Marks methods as static, whenever possible (devirtualization).

标记方法为static(具体化)
method/marking/final
Marks methods as final, whenever possible.

标记方法为final
(⇒ code/removal/advanced)

method/removal/parameter
Removes unused method parameters.

删除未使用的方法参数
(⇒ code/simplification/advanced)

method/propagation/parameter
Propagates the values of method parameters from method invocations to the invoked methods.

从方法的invocations传递方法参数值到 实际调用方法的地方invoked methods
(⇒ code/simplification/advanced)

method/propagation/returnvalue
Propagates the values of method return values from methods to their invocations.

传递方法的返回值 从方法到它们被调用的地方
method/inlining/short
Inlines short methods.

内联短方法
method/inlining/unique
Inlines methods that are only called once.

内联 仅被调用一次(或者说只被一个地方调用)的短方法
method/inlining/tailrecursion
Simplifies tail recursion calls, whenever possible.

简化尾递归 (尾递归转循环)
code/merging
Merges identical blocks of code by modifying branch targets.

合并相同的代码块
code/simplification/variable
Performs peephole optimizations for variable loading and storing.

变量加载和存储时 使用peephole optimization(窥孔优化)技术
code/simplification/arithmetic
Performs peephole optimizations for arithmetic instructions.

计算指令 用 窥孔优化
code/simplification/cast
Performs peephole optimizations for casting operations.

类型转换 用 窥孔优化
code/simplification/field
Performs peephole optimizations for field loading and storing.

属性加载和存储 用 窥孔优化
(⇒ code/removal/simple)

code/simplification/branch
Performs peephole optimizations for branch instructions.

分支指令 用 窥孔优化
code/simplification/string
Performs peephole optimizations for constant strings.

常量字符串 用 窥孔优化
(best used with code/removal/advanced)

code/simplification/advanced
Simplifies code based on control flow analysis and data flow analysis.

简化代码 基于控制流分析和数据流分析 
(⇒ code/removal/exception)

code/removal/advanced
Removes dead code based on control flow analysis and data flow analysis.

删除死代码 基于控制流分析和数据流分析
(⇒ code/removal/exception)

code/removal/simple
Removes dead code based on a simple control flow analysis.

删除死代码 基于一个简单的控制流分析
code/removal/variable
Removes unused variables from the local variable frame.

从本地变量框架中,删除 未使用的变量
code/removal/exception
Removes exceptions with empty try blocks.

当try-catch中,try块内为空时,删除exceptions
code/allocation/variable
Optimizes variable allocation on the local variable frame.

在本地变量框架中 优化变量分配

注意

· 上一句保护,下一句启用modifers, 启用无效; 上一句启用modifiers,下一句保护,保护有效。 重在保护

· 使用了-dontshrink|dontoptimize|dontobfuscate 这些全局选项后,那么再使用相应的kepp modifiers 无效

· 当不使用-dontoptimize选项时,则-optimizations optimization_filter才有效

· 测试发现jdk中就有优化不通过的地方,并且这个优化时间很长时间,还可能造成优化程序不结束(一直在运行,结束不了)

   所以一般还是直接使用 -dontoptimize。sdk中的proguard的配置文件也是这么写的。如果你想专业点,自行调试吧~


示例

[plain] view plain copy
 print?在CODE上查看代码片派生到我的代码片
  1. -dontoptimize  #不优化  
  2. -dontpreverify #不预校验  
  3.   
  4. #保持源文件和行号的信息,用于混淆后定位错误位置  
  5. -keepattributes SourceFile,LineNumberTable  
  6.   
  7. -libraryjars class_path  #不处理 class_path指定的文件  
  8.   
  9. -dontusemixedcaseclassnames  #不使用大小写混合类名  
  10. -dontskipnonpubliclibraryclasses #不跳过jars中的非public classes。在proguard4.5时,是默认选项  
  11. -verbose  
  12.   
  13. -flattenpackagehierarchy com.stone.myapplication.interfaces # 将包里的类混淆成n个再重新打包到一个一个的package中  
  14. -repackageclasses com.stone.myapplication.interfaces #将包里的类混淆成n个再重新打包到一个统一的package中 会覆盖flattenpackagehierarchy选项  
  15.   
  16. -keepattributes *Annotation* #保持含有Annotation字符串的 attributes  
  17. -keep public class com.google.vending.licensing.ILicensingService  
  18. -keep public class com.android.vending.licensing.ILicensingService  
  19.   
  20. #保持 本化方法及其类声明  
  21. -keepclasseswithmembernames class * {   
  22.     native <methods>;  
  23. }  
  24. #保持view的子类成员: getter setter  
  25. -keepclassmembers public class * extends android.view.View {   
  26.    void set*(***);  
  27.    *** get*();  
  28. }  
  29. #保持Activity的子类成员:参数为一个View类型的方法   如setContentView(View v)  
  30. -keepclassmembers class * extends android.app.Activity {  
  31.    public void *(android.view.View);  
  32. }  
  33. #保持枚举类的成员:values方法和valueOf  (每个enum 类都默认有这两个方法)  
  34. -keepclassmembers enum * {  
  35.     public static **[] values();  
  36.     public static ** valueOf(java.lang.String);  
  37. }  
  38. #保持Parcelable的实现类和它的成员:类型为android.os.Parcelable$Creator 名字任意的 属性  
  39. -keep class * implements android.os.Parcelable {  
  40.   public static final android.os.Parcelable$Creator *;  
  41. }  
  42. #保持 任意包名.R类的类成员属性。  即保护R文件中的属性名不变  
  43. -keepclassmembers class **.R$* {  
  44.     public static <fields>;  
  45. }  
  46. #不警告 support包  
  47. -dontwarn android.support.**  
  48.   
  49. -keepattributes Signature   #保持签名  
  50. #下面三个gson相关  
  51. -keep class sun.misc.Unsafe {*;}  
  52. -keep class com.google.gson.examples.android.model.**{*;}  
  53. -keep class com.tv.kuaisou.bean.* {*;}  
  54.   
  55. -keep public class * extends android.app.Activity  
  56. -keep public class * extends android.app.Application  
  57. -keep public class * extends android.app.Service  
  58. -keep public class * extends android.content.BroadcastReceiver  
  59. -keep public class * extends android.content.ContentProvider  

相关文章推荐

ProGuard解析

运行Proguard,立即输入(当然你需要定位到proguard.jar的目录下面): java -jar proguard.jar options …  proguard.jar在lib目录下(...

JAVA之代码混淆proguard基础(一)

一官方网站用法               http://proguard.sourceforge.net/index.html#/manual/examples.html...

混淆利器proguard的用法

利用java编程,最头痛的就是代码的反编译,现在的反编译工具也比较多,只要一反编译,大部分都能被还原过来。这时候,用JAVA写的PROGUARD横空出世了,它集压缩、优化、混淆于一体。下面介绍一下它的...

Android 代码混淆 选项说明

Class Specifications 类规范 完整语法 [@annotationtype] [[!]public|final|abstract|@ ...] [!]interface|clas...

Android proguard 详解

本文转载于:http://blog.csdn.net/banketree/article/details/41928175 简介 Java代码是非常容易反编译的。为了很好的...

android学习之代码混淆小结

之前一直没有对代码混淆有一个很明确的认识,今天重新对代码混淆做了一番了解,并记录一下在android studio上是如何做代码混淆的。第一步:buildTypes { release...

Android 混淆 (不定期完善第三方混淆规则)

开启混淆在AS中,借助于SDK中自带的Proguard工具,开启混淆只需要在release闭包中添加如下两行代码: release { minifyEnabled...

Android 混淆代码总结

Android 混淆代码总结

Android混淆规则

# If your project uses WebView with JS, uncomment the following # and specify the fully qualified cl...

写给Android开发者的混淆使用手册

【转载自】:简书--写给Android开发者的混淆使用手册 【作者】:光源_Android 【链接】:http://www.jianshu.com/p/158aa484da13 综述 ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android 代码混淆选项详细说明
举报原因:
原因补充:

(最多只允许输入30个字)