您的位置:首页 > 移动开发 > Android开发

ProGuard(混淆器)

2013-07-17 18:07 197 查看
        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文件之前,会自动地对应用程序字节码进行混淆处理。而在调试模式中进行编译则不会调用混淆器,因为那样调试会更加繁重。
         运行ProGuard之后的输出文件有:
             dump.txt
                      描述.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调用的方法。
   动态引用的属性和方法。
       虽然 默认的[b]proguard.cfg[/b]文件尝试把普遍情况都考虑在内(

还有一些没考虑到的情况,就会被混编或移除),但当你的程序去访问一个已经被ProGuard重命名的类时,就会遇到一些类似ClassNotFoundException的异常。

     遇到这种情况可以在proguard.cfg文件中加入-keep命令来修复。例如: 
  

-keep public class <MyClass>
          -keep命令有很多可选项(option)和需要注意的地方,如果想了解更多,可以阅读《proguard用户手册》。手册里面需要关注内容的是keep选项综述和举例部分。
《proguard用户手册》里的“问题解决方案”章节介绍了一些在混淆过程中可能遇到的其他常见问题。

   解码混淆过的堆栈跟踪信息

           当混淆代码并输出一个堆栈跟踪信息时,方法名都被混淆了(即被重命名),虽然可以进行调试,但是调试变得困难了。

幸运的是,每当混淆器运行时,都会输出一个<project_root>/bin/proguard/mapping.txt文件,该文件展示了从类、方法和属性的原始名字到混淆后的名字的对应关系。
           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工具从标准输入读取信息。

已发布的应用的调试注意事项
      保存好每一个已发布给用户的应用的mapping.txt文件。如果有用户使用应用时遇到bug并提交堆栈跟踪信息给你,你可以通过编译发布应用时保存的mapping.txt文件副本来调试bug。每次编译发布应用程序时mapping.txt文件都会被覆盖,所以需要保存比较必要的版本的mapping.txt文件。

        例如:假设你发布了一个应用程序并且为开发该应用程序的新版本在该应用程序的基础上增加一些新功能。接着将会启动ProGuard编译出一个新的发布版本。该操作会覆盖之前发布时产生的mapping.txt文件。突然有一个用户提交来自之前发布版本的bug报告,该报告包含了堆栈跟踪信息。由于对应用户手机上安装的应用程序的版本的mapping.txt文件已经不存在了,所以没办法对用户的堆栈跟踪信息进行调试了。
 
      还有存在其他覆盖mapping.txt文件的情况,所以对于每一个可能需要调试的版本,都要确保有一份mapping.txt文件副本。
 
      如何保存mapping.txt文件副本自由决定。例如:可以根据版本和编译号来重命名mapping.txt文件,或者可以跟从源代码对mapping.txt文件进行版本控制。

翻译可能有些部分会与原文有点差异,谨慎附上原文网址:http://developer.android.com/tools/help/proguard.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息