ProGuard是一个开源的Java代码混淆器。它可以混淆Android项目里面的java代码,但是不能混淆资源,实际效果是会把类名变成各种字母,变量名或者方法名字改变成abc等,这里我要说明的是代码混淆后是不能防止反编译,只是增加了代码的阅读困难度,如果真的下功夫,也是能够搞懂源代码。
下面介绍下ProGuard这个java代码的开源混淆器。
java源代码(.java文件)通常被编译为字节码(.class文件)。而完整的程序或程序库通常被压缩和发布成java文档(.jar文件)。字节码比
Java源文件更简洁,但是它仍然包含大量的无用代码,尤其它是一个程序库的时候。ProGuard的压缩程序操作能分析字节码,并删除无用的类、字段和方法。程序只保留功能上的等价,包括异常堆栈描述所需要的信息。
通常情况下,编译后的字节码仍然包含了大量的调试信息:源文件名,行号,字段名,方法名,参数名,变量名等等。这些信息使得它很容易被反编译和通过逆向工程获得完整的程序。有时,这是令人厌恶的。例如像ProGuard这样的混淆器就能删除这些调试信息,并用无意义的字符序列来替换所有名字,使得它很难进行逆向工程,它进一步地精简代码。除了异常堆栈信息所需要的类名,方法名和行号外,程序只会保留功能上的等价。通过以上的了解,你应该明白为什么需要混淆了。
现在Android开发绝大部分都用studio了,还在用eclipse的同学如果不是公司强制要求或者有特殊的需求,这里推荐使用Android
Studio这个谷歌官方的IDE,非常方便,下面说下在studio下混淆的方法。
只需要在build.grade 的配置文件中配置如下即可:
minifyEnabled配置为true,引入配置好的混淆文件
release {
minifyEnabledtrue
proguardFilesgetDefaultProguardFile('proguard-android.txt'),'proguard-rules.pro'
}
混淆规则如下:
-libraryjars class_path
应用的依赖包,如android-support-v7
-keep [,modifier,...]class_specification
不混淆的类
-keepclassmembers
[,modifier,...]class_specification 不混淆类的成员
-keepclasseswithmembers
[,modifier,...]class_specification 不混淆类及其成员
-keepnames class_specification
不混淆类及其成员名
-keepclassmembernamesclass_specification不混淆类的成员名
-keepclasseswithmembernamesclass_specification不混淆类及其成员名
-assumenosideeffects
class_specification调用没有影响的情况,在proguard代码优化时会将该调用remove掉。如system.out.println和Log.v等等
-dontobfuscate 不混淆输入的类文件
-obfuscationdictionary {filename}
使用给定文件中的关键字作为要混淆方法的名称
-overloadaggressively
混淆时应用侵入式重载
-useuniqueclassmembernames确定统一的混淆类的成员名称来增加混淆
-flattenpackagehierarchy
{package_name}重新包装所有重命名的包并放在给定的单一包中
-repackageclass {package_name}
重新包装所有重命名的类文件中放在给定的单一包中
-dontusemixedcaseclassnames混淆时不会产生形形色色的类名
-keepattributes {attribute_name,…}
保护给定的可选属性,例如LineNumberTable, LocalVariableTable, SourceFile,
Deprecated,Synthetic, Signature, and
InnerClasses.
-renamesourcefileattribute {string}设置源文件中给定的字符串常量
不能被混淆的类
在AndroidManifest中配置的类,比如四大组件
JNI调用的方法
反射用到的类
WebView中JavaScript调用的方法
Layout文件引用到的自定义View
实际使用要注意第三方库的混淆规则要看它们的官方文档,都会有混淆的说明。