精华Android中ProGuard的使用ZZ 分类: Android安装及配置 2014-05-30 10:55 139人阅读 评论(0) 收藏
http://www.apkbus.com/android-122624-1-1.html
=================原创教程============================
1、什么是ProGuard 工具?
ProGuard 是 通过移除没用的代码、重命名相关类和方法等方式对代码进行优化、压缩、混淆的一个工具。
android中ProGuard已经被整合到开发工具中,官方强烈建议使用。对于调试模式,该工具不会被启用。
2、ProGuard 的使用
当你创建项目时,在项目的根目录下会自动生成proguard.cfg文件,该文件就是ProGuard的配置文件,使用方法也比较简单:在project.properties文件中添加"proguard.config=proguard.cfg"即可。默认生成的ProGuard文件只是用与一般的情况(仅仅覆盖了Android中几个比较重要的类)。所以大部分情况下我们需要自己定制该配置文件。
当然,上述情况是proguard.cfg文件位于项目的根目录下,如果你愿意你也可以挪动到别的地方,不过properties文件中需指明路径。
项目发布时会自动调用ProGuard工具混淆,从而在项目文件夹下面会生成
dump.txt: 描述.apk文件中所有类文件间的内部结构
mapping.txt:列出了原始的类,方法和字段名与混淆后代码间的映射。这个文件很重要,当你从release版本中收到一个bug报告时,可以用它来翻译被混淆的代码。
seeds.txt:列出了未被混淆的类和成员
usage.txt:列出了从.apk中删除的代码
这几个文件主要描述了整个混淆的过程包括名称替换部分的详细描述。由于混淆后的代码输出的调试信息有可能因为混淆也变得难以识别,这时你就需要借助这几个文件来查询原始信息了。
3、ProGuard的配置
一般情况下ProGuard会正常工作,但是别忘了它也有犯浑的时候。有时间他会把项目中实际有用的代码移除,然后向您报告ClassNotFoundException!!例如:
- 仅仅被AndroidManifest.xml文件引用的类
- 由JNI调用的方法
-
动态引用的属性和方法
proguard.cfg配置文件中添加 -keep public class 即可。
当然就代码安全性而言,SDK中还给出了以下的建议以保护敏感代码:
- 多使用方法嵌套调用
- 少使用字符串常量,尽量动态构造
-
使用反射进行方法调用
相信大家都能看明白,${sdk.dir}/tools/proguard/proguard-android.txt文件引用的是默认配置(即所有项目通用的),proguard-project.txt是项目下面针对该项目的配置,最终配置由这两部分组成。
=======================我是分割线====================================
(以下内容摘自互联网)
===================================================================
-include {filename}
-basedirectory {directoryname}
-injars {class_path}
-outjars {class_path}
-libraryjars {classpath}
-dontskipnonpubliclibrary
-dontskipnonpubliclibrary
-keep {Modifier} {class_specification}
-keepclassmembers {modifier}{class_specification}
-keepclasseswithmembers {class_specification}
-keepnames {class_specification}
-keepclassmembernames {class_specification}
-keepclasseswithmembernam
-printseeds {filename}
压缩
-dontshrink
-printusage {filename}
-whyareyoukeeping {class_specification}
优化
-dontoptimize
-assumenosideeffects {class_specification}
-allowaccessmodification
混淆
-dontobfuscate
-printmapping {filename}
-applymapping {filename}
-obfuscationdictionary {filename}
-overloadaggressively
-useuniqueclassmembername
-flattenpackagehierarchy {package_name}
-repackageclass {package_name}
-dontusemixedcaseclassnam
-keepattributes {attribute_name,...}
-renamesourcefileattribut
===========================Theend===========================================
===============以下内容为对ProGuard官方文档的翻译及总结=================================
ProGuard的工作原理:
ProGuard 读取jars(包括wars, ears, zips, ordirectories)。input这一部分可以是源文件,源文件的类名称与混淆后类名称一一对应。
凡是正常编译所需的jar文件都需要添加到 Inputjars中。jar文件一般不会被处理,但是你仍需将它们添加到classpath中。
应用程序入口
为了识别项目中哪些类需要保留,那些需要被移除,你需要定义程序的入口,如main函数的类,activity等。
shrinking:这一步中,ProGuard会从入口处递归查询,那些没有被用到的类和方法将会被移除。
optimization :这一步中,ProGuard会进一步优化程序,非公开的类和方法将会有可能被 private, static,or final化,没有用的参数将会被移除,有一些函数将会被内联。
obfuscation:这一步中:对于非入口的类与方法,ProGuard将会对类和其中的方法属性进行重命名,
preverification :该步仅适用于入口程序无关紧要的项目。
对于动态加载的类或方法,最好也要将其作为入口点。
ProGuard的使用
java -jar proguard.jar options ...
或者将options写入到相应的配置文件中
java -jar proguard.jar @myconfig.pro
配置文件中使用“#”作为行注释。
多余的空格将会被忽略,如果文件名中含有空格那么需要使用单引号或者双引号。
配置可以任意分组,其数量是不被限制的。
配置不分先后顺序,为了方便检索,你可以按照首字母进行排序。
input/output相关命令
-include filename 包含其他的配置文件
-basedirectorydirectoryname
-injars class_path 设置将要被处理的jar(or wars, ears, zips, ordirectories)文件。默认情况下所有非class文件将会被按原样拷贝。所以,请注意中间文件。
-outjars class_path 指定对应的输出文件,但是应避免将输出文件直接覆盖输入文件,如果不配置outjars将不会有输出。
注:input 与 output都可以设置过滤器,可指明多个。
-libraryjars class_path指明库文件位置这些jar文件不会被输出到output中。库文件中的类应是被继承而不仅仅是被使用的。需要注意的是ProGuard不会从基准文件夹或者ProGuard的运行文件夹中寻找库文件。
-skipnonpubliclibraryclas
-dontskipnonpubliclibrary
-dontskipnonpubliclibrary
-keepdirectories [directory_filter]声明output中需要保留的目录,默认情况下为减小jar文件的大小,目录都将被删除。可以添加过滤器,如果不加过滤器那么所有的目录都将被保留。
-target version 设置版本号,可以为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 强制处理。
Keep Options(保证不被移除)
-keep [,modifier,...] class_specification声明类和类中成员作为入口点保留。例如对于普通程序,需要声明Main类及其main函数,为了处理类库你需要将里面所有的公共域都声明为入口点。
-keepclassmembers [,modifier,...] class_specification如果类被保留那么类成员也将被保留,例如保留实现Serizable的类中所有的域。
-keepclasseswithmembers [,modifier,...] class_specification声明含有指定域的类都被保留,而不必一一列出,如保留所有含有main的类。
-keepnamesclass_specification
-keepclasseswithmembernam
-printseeds[filename]
Shrinking Options
-dontshrink 声明不压缩输入文件夹,默认情况下使用压缩的。
-printusage [filename] 列出被移除的代码。
-whyareyoukeeping class_specification 列出被移除的原因
Optimization Options
-dontoptimize 不优化。默认优化。
-optimizations optimization_filter专家级别的可选项,优化项过滤器。
-optimizationpasses n优化几轮,默认一轮,如果优化一轮后发现没有可优化的项目了,直接就停止了。
-assumenosideeffectsclass_specification
-allowaccessmodification声明处理过程中,允许扩大访问修饰符。例如将get方法内联会将相关属性的访问修饰符设为public。如果设计为类库就应避免使用该设置项。
-mergeinterfacesaggressiv
ObfuscationOptions
-dontobfuscate 不使用混淆,默认使用混淆。类及其中的域都会被命名为一个更加简洁的名称。
-printmapping [filename] 将混淆前后对应的名称输出到指定的地点。
-applymapping filename 使用以前输出的混淆前后mapping。
-obfuscationdictionaryfilename
-classobfuscationdictiona
-packageobfuscationdictio
-overloadaggressively 声明可以使用扩展性的重载(允许只有返回值不同)
-useuniqueclassmembername
-dontusemixedcaseclassnam
-keeppackagenames [package_filter] 声明不被混淆的包名,过滤器可以使用 * ? 及**或!
-flattenpackagehierarchy [package_name]将所有的包名重构,所有类放到指定的一个包中。
-keepattributes [attribute_filter]声明应被保留的属性,可以使用通配符。
-keepparameternames 含有指定声明方法参数或者类型的被保留
-renamesourcefileattribut
-adaptclassstrings [class_filter]声明与类名一致的字符串常量也将被混淆。
-adaptresourcefilenames [file_filter]指明将要被重命名的源文件,
-adaptresourcefilecontent
====================That's