ProGuard的用途
ProGuard通过删除没用的代码和使用可读性差的名字(例:a、b、c等)替代已规律命名的类、字段和方法,来对代码进行压缩、优化和混淆。这样做带来的好处是apk文件较小并且难以进行反编译。 所以如果想保护程序代码在发布后不容易被别人抄袭,可以采用 ProGuard进行编译。
ProGuard被集成到android 编译系统中,所以不必去手动调用它。还有一点需要提醒, ProGuard只有在发布模式下编译应用程序才会被使用来混淆代码,但在调试模式下是不会被使用的(因为根本没必要)。虽然ProGuard没有被强制使用,但是还是推荐开发者使用。
这篇文章描述了怎样启用并配置ProGuard,以及使用跟踪(retrace)工具对ProGuard的堆栈跟踪信息(stack traces)进行解码。
启用ProGuard
当你新建一个Android工程后,工程的根目录下会自动产生一个proguard.cfg文件。如果该文件没有产生,不必担心,大不了自己在工程根目录下建立proguard.cfg文件就行了(不影响其功能)。这个.cfg文件定义了ProGuard怎样优化和混淆你的代码,所以懂得怎样根据你的需要来定制混淆是非常重要的。默认的配置文件只考虑到通用情况,所以根据你的实际情况,很可能需要对它进行修改。接下来的内容是关于如何通过定制proguard.cfg文件。
为了在Ant或者Eclipse编译过程中能够使用ProGuard,需要在<project_root>/project.properties文件中设置proguard.config属性。
该路径可以是绝对路径或者工程根目录的相对路径。
如果proguard.cfg文件在默认位置(工程的根目录),可以这样指定位置:
proguard.config = proguard.cfg
proguard.config = /path/to/proguard.cfg
当在发布模式下,通过运行ant release,或者使用Eclipse中Export Wizard编译应用程序时,编译系统会自动地去检查proguard.config属性是否被设置。如果被设置了,编译器在把所有东西打包成.apk文件之前,会自动地对应用程序字节码进行混淆处理。而在调试模式中进行编译则不会调用混淆器,因为那样调试会更加繁重。
描述.apk包中所有class文件的内部结构。
mapping.txt
列出了源代码与混淆后的类、方法和属性名字之间的映射。这个文件对于在编译之后得到的bug报告非常有用,因为它把混淆的堆栈跟踪信息反翻译为源代码中的类、方法和成员名字。
seeds.txt
列出那些未混淆的类和成员。
usage.txt
列出从.apk中剥离的代码。
这些文件放在以下目录中:
- 使用Ant时: <project_root>/bin/proguard
- 使用Eclipse时: <project_root>/proguard
注意: 每次在发布模式下编译,这些文件都会被最新的文件覆盖。所以每次发布程序时候,为了反混淆来自编译时产生的bug报告,请保存这些文件的一个拷贝。对于为什么要保存这些文件的重要性的更多信息,请查看程序发布调试注意事项。
配置ProGuard
在大多数情况下,proguard.cfg文件的默认配置可以满足需求。然而,大多数情况下ProGuard很难做出正确的分析,并且它可能会删除一些它看来是无用的代码,但这些代码对于程序来说却是必不可少的。例子如下:
- 一个仅引用于AndroidManifest.xml文件的类。
- 一个通过JNI调用的方法。
- 动态引用的属性和方法。
虽然 默认的proguard.cfg文件尝试把普遍情况都考虑在内(还有一些没考虑到的情况,就会被混编或移除),但当你的程序去访问一个已经被ProGuard重命名的类时,就会遇到一些类似ClassNotFoundException的异常。
遇到这种情况可以在proguard.cfg文件中加入-keep命令来修复。例如:
-keep public class <MyClass>
-keep命令有很多可选项(option)和需要注意的地方,如果想了解更多,可以阅读《proguard用户手册》。手册里面需要关注内容的是keep选项综述和举例部分。
Windows系统中retrace.bat脚本命令或者Linux和Mac OS X系统中retrace.sh脚本命令能够把混淆后的堆栈跟踪信息转换成可阅读文件。retrace工具被存放在<sdk_root>/tools/proguard/bin目录下(路径跟原文有点出入,但是是实际情况,所以必须告诉读者)。
运行retrace工具的命令语法是:
retrace.bat|retrace.sh [-verbose] mapping.txt [<stacktrace_file>]
例如:
retrace.bat -verbose mapping.txt obfuscated_trace.txt
如果没有为<stracktrace_file>指定值,那么retrace工具从标准输入读取信息。
翻译可能有些部分会与原文有点差异,谨慎附上原文网址:http://developer.android.com/tools/help/proguard.html