ProGuard
启用ProGuard
当你新创建一个Android 工程时,在工程的根目录下会自动创建一个 proguard.cfg文件,这个文件定义了ProGuard将如何优化和混淆代码,所以理解如何根据自己的需要自定义这个文件非常重要。默认的配置只能覆盖到通用的情况,所以很可能会根据自己的要求对它进行编辑。定制自己的Proguard配置文件请看配置Proguard。
作为Ant或者Eclipse编译的一部分开启ProGuard,只需要在<project_root>/default.properties文件中设置proguard.config 属性。路径设置可以是相对路径或者绝对路径。
如果你使用
proguard.cfg
默认的位置(工程的根目录),可以这样指定:
proguard.config=proguard.cfg
也可以把它移动到其他位置,指定绝对路径:
proguard.config=/path/to/proguard.cfg
当使用 ' ant release ' (Ant) 或使用Eclipse Export Wizard 编译release 版本时,编译系统会自动检查 是否设置了proguard.config 属性,编译系统会自动检查 是否设置了proguard.config属性,如果设置了,那么ProGard会在打包 .apk 文件之前自动处理应用程序的字节码。编译debug版本不会触发ProGuard ,这样可以避免它给调试带来的麻烦。
ProGuard运行之后会生成以下四个文件:
dump.txt
描述 .apk 中所有类文件的内部结构。
mapping.txt
列举原始的类和混淆过的类的映射关系。当你收到一个release版本的bug report 的时候, 这个文件有非常重要的作用,它可以将混淆的stack trace 转回为原始的类名,方法名,成员名。详情请见 解码混淆的Stack Traces。
seeds.txt
列举没有混淆的类和成员。
usage.txt
列举从.apk中删除的代码。
这些文件会生成在下面的目录位置:
- <project_root>/bin/proguard (如果使用Ant)。
- <project_root>/proguard (如果使用Eclipse)。
注意: 每次编译Release 版本,ProGuard会重新生成这些文件并覆盖之前的文件。所以为了能顺利解析Release版本的BugReport,最好每次Release的时候都保存一份这些文件。详情请见 发布应用的注意事项。
一般情况,proguard.cfg中的默认配置就足够了。尽管如此,很多情况下ProGuard作出正确的分析十分困难,它可能移出自认为没用的代码,但是应用程序确实需要。例如:
- 只在 AndroidManifest.xml 文件中引用的类 。
- 从 JNI 调用的方法。
- 动态引用的字段和方法。
默认的 proguard.cfg 文件会试图覆盖通用的情况,但是你可能遇到诸如 CalssNotFoundException 这样的异常,当ProGuard移出了你的应用程序调用的一个类的时候。
当ProGuard错误地移除了代码,你可以通过在 proguard.cfg 中添加一行 -keep 选项来修复这种错误。例如:
-keep publicclass<MyClass>
当使用 -keep的时候有很多选项,强烈建议你阅读 ProGuard 指南 。Keep选项概览 和 用法举例 可能会有所帮助。ProGuard 的常见问题 模块汇集了其他常见问题。
混淆过的代码输出的 stack trace 中晦涩的方法名会给调试带来很大的困难。幸运的是,ProGuard运行时生成了一个 <project_root>/bin/proguard/mapping.txt 文件,此文件记录了原始的类、方法、字段名称和混淆后的名字的对应关系。
Windows 脚本 retrace.bat 和 Linux/Mac OS X 脚本 retrace.sh 可以将混淆的stack trace 转变为可读的。在<sdk_root>/tools/proguard/目录下可以找到它们。执行 retrace 工具的语法是:
retrace.bat|retrace.sh [-verbose] mapping.txt [<stacktrace_file>]
例如:
retrace.bat -verbose mapping.txt obfuscated_trace.txt
每次发布 release 版本时都要保存mapping.txt 文件。每次编译 release 版本都保存一份mapping.txt 文件可以保证 当用户遇到Bug提交一个混淆过的 stack trace 时你能够顺利的调试。一个工程的mapping.txt 文件每次编译 release 版本时都会重写,所以必须小心保存需要的版本。
举个例子:你发布了一个应用然后继续在为下一个版本开发新的功能,不久后你会使用ProGuard编译一个 release 版本。这会覆盖之前的 mapping.txt文件。假如用户提交了一个 bug report,包含了已发布版本的 stacktrace, 你将无法进行调试,因为用户使用版本的mapping.txt 已经没有了。还有其他一些情况mapping.txt也会被重写,所以确保为每次发布都保存一份。
如何保存mapping.txt文件由你决定。比如,可以用编译的版本号重命名或者使用版本控制。
原文链接:http://blog.csdn.net/vallay_star/article/details/7078036