




已阅读5页,还剩6页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Android打包混淆作为Android应用开发者,不得不面对一个尴尬的局面,就是自己辛辛苦苦开发的应用可以被别人很轻易的就反编译出来。Google似乎也发现了这个问题,从SDK2.3开始我们可以看到在android-sdk-windowstools下面多了一个proguard文件夹。ProGuard是一个免费的java类文件压缩、优化和混淆器。它探测并删除没有使用的类、字段、方法和属性。它删除没有用的说明并使用字节码得到最大优化。Proguard作为一个代码混淆的工具,它使用无意义的名字来重命名类、字段和方法。通过proguard,别人即使反编译你的apk包,也只会看到一些让人很难看懂的代码,从而达到保护代码的作用。一、 ProGuard相关的一些定义通过ProGuard得到的更精简的jar文件意味着只需要更小的存储空间;网络传输更省时;装载速度更快和占用更小的内存空间。另外,ProGuard非常快速和高效,它仅仅只花费几秒钟和几兆的内存在处理程序。它处理的顺序是先压缩,然后优化,最后才进行混淆。1. 什么是压缩? Java 源代码(.java文件)通常被编译为字节码(.class文件)。而完整的程序或程序库通常被压缩和发布成Java文档(.jar文件)。字节码比 Java源文件更简洁,但是它仍然包含大量的无用代码,尤其它是一个程序库的时候。ProGuard的压缩操作能分析字节码,并删除无用的类、字段和方法。程序只保留功能上的等价,包括异常堆栈描述所需要的信息。2. 什么是混淆? 通常情况下,编译后的字节码仍然包含了大量的调试信息:源文件名,行号,字段名,方法名,参数名,变量名等等。这些信息使得它很容易被反编译和通过逆向工程获得完整的程序。但ProGuard的混淆器功能,能删除这些调试信息,并用无意义的字符序列来替换所有名字,使得它很难进行逆向工程,且进一步的精简了代码。除了异常堆栈信息所需要的类名,方法名和行号外,程序只会保留功能上的等价。ProGuard混淆的方法有很多,主要是以下几方面:1) 更名,将私有类,私有的成员,方法体内部的变量名改名,改成a,b,c等等; 2) 改变逻辑的流向,如将if条件取反,if/else对换;3) 等价代码,如将循环改成GOTO;4) 无效代码,插入不可及的无用代码;3. ProGuard支持那些种类的优化?除了在压缩操作删除的无用类,字段和方法外,ProGuard也能在字节码级提供性能优化,内部方法有:1) 常量表达式求值 2) 删除不必要的字段存取 3) 删除不必要的方法调用 4) 删除不必要的分支 5) 删除不必要的比较和instanceof验证 6) 删除未使用的代码 7) 删除只写字段 8) 删除未使用的方法参数 9) 像push/pop简化一样的各种各样的peephole优化 10) 在可能的情况下为类添加static和final修饰符 11) 在可能的情况下为方法添加private, static和final修饰符 12) 在可能的情况下使get/set方法成为内联的 13) 当接口只有一个实现类的时候,就取代它 14) 选择性的删除日志代码 实际的优化效果是依赖于你的代码和执行代码的虚拟机的。简单的虚拟机比有复杂JIT编译器的高级虚拟机更有效。无论如何,你的字节码会变得更小。但仍有一些明显需要优化的技术不被支持: 1) 使非final的常量字段成为内联 2) 像get/set方法一样使其他方法成为内联 3) 将常量表达式移到循环之外 4) Optimizations that require escape analysis 二、 ProGuard的使用1. ProGuard的命令行用法:用命令行执行ProGuard的命令如下: java jar proguard.jar options 你也可以把这些属性写在配置文件里,运行时,我们只需要指定这个配置文件就行了,例如: java jar proguard.jar 配置文件的格式要按照ProGuard提供的格式来写,这可以参考ProGuard例子里的配置文件来配置适合你的应用系统的ProGuard配置文件。ProGuard提供了图形界面的配置和运行程序(proguardgui),你可以在界面上配置你想要的参数,然后运行即可。前面提到的要手动写的配置文件也可以用图形界面来配置和生成。 如果你要在Ant里运行ProGuard,只需要添加一一个如下的target即可: 你只需要制定lib.dir和src.dir属性就行了。建议大家把ProGuardGUI当成一个生成配置文件的向导来使用,这样我们只需要修改配置文件而不用重新写一个配置文件。 2. ProGuard在ADT中的用法在Android 2.3以前,混淆Android代码只能手动添加proguard来实现代码混淆,非常不方便,而2.3以后,Google已经将这个工具加入到了SDK的工具集里,具体路径:SDKtoolsproguard。当创建一个新的Android工程时,在工程目录的根路径下,会出现一个proguard的配置文件proguard.cfg。也就是说,我们可以通过简单的配置,在我们的elipse工程中直接使用ProGuard混淆Android工程。但在新版本的ADT创建项目时,混码的文件不再是proguard.cfg,而是perties和proguard-project.txt。如果需要对项目进行全局混码,只需要进行一步操作,将perties的中“# proguard.config=$sdk.dir/tools/proguard/proguard-android.txt:proguard-project.txt”的“#”去掉就可以了。在老版本中,创建项目的时候,会给出proguard.cfg,但是在的新版中创建项目则不会有任何提示。这个时候需要只要将proguard.cfg的内容加入到proguard-project.txt中,再根据自己的需要进行编辑即可。3. 运行混淆器之后输出的文件运行混淆器之后输出的文件有:1) dump.txt 描述.apk包中所有class文件的内部结构。2) mapping.txt列出了源代码与混淆后的类,方法和属性名字之间的映射。这个文件对于在构建之后得到的bug报告是有用的,因为它把混淆的堆栈跟踪信息反翻译为源代码中的类,方法和成员名字。更多信息,查看解码混淆过的堆栈跟踪信息。3) seeds.txt列出那些未混淆的类和成员。4) usage.txt列出从.apk中剥离的代码。这些文件放在以下目录中:1/bin/proguard/ 当你使用Ant时2/proguard/ 当你使用Eclipse时注意:每次在发布模式下构建时,这些文件都会被最新的文件覆盖。所以每次发布程序时候,为了反混淆来自构建时产生的bug报告,请保存这些文件的一个拷贝。4. 解码混淆过的堆栈跟踪信息(Decoding Obfuscated Stack Traces)当混淆代码并输出了一个堆栈调试信息时,这些方法名字是混淆过的,虽然可以进行调试,但是调试变得困难。幸运的是,每当混淆器运行时候,它都会输出到文件/bin/proguard/mapping.txt中,该文件包含了从原始类,方法和属性名字到混淆后名字的映射。Windows系统中retrace.bat脚本命令或者Linux和Mac OS X系统中retrace.sh脚本命令能把混淆后的堆栈调试信息转换为可以理解的文件。它被放在/tools/proguard/目录下。运行retrace工具的命令语法是:retrace.bat|retrace.sh -verbose mapping.txt 例如:retrace.bat -verbose mapping.txt obfuscated_trace.txt如果你没有为指定值,那么retrace工具从标准输入读取。三、 proguard的使用参数1. 最常用的配置选项: -dontwarn 缺省proguard 会检查每一个引用是否正确,但是第三方库里面往往有些不会用到的类,没有正确引用。如果不配置的话,系统就会报错。 -keep 指定的类和类成员被保留作为入口 。 -keepclassmembers 指定的类成员被保留。 -keepclasseswithmembers 指定的类和类成员被保留,假如指定的类成员存在的话。2. 详细参数-include filename 从给定的文件中读取配置参数 -basedirectory directoryname 指定基础目录为以后相对的档案名称 -injars class_path 指定要处理的应用程序jar,war,ear和目录 -outjars class_path 指定处理完后要输出的jar,war,ear和目录的名称 -libraryjars classpath 指定要处理的应用程序jar,war,ear和目录所需要的程序库文件 -dontskipnonpubliclibraryclasses 指定不去忽略非公共的库类。 -dontskipnonpubliclibraryclassmembers 指定不去忽略包可见的库类的成员。 -dontwarn 缺省proguard 会检查每一个引用是否正确,但是第三方库里面往往有些不会用到的类,没有正确引用。如果不配置的话,系统就会报错。保留选项 -keep Modifier class_specification 保护指定的类文件和类的成员 -keepclassmembers modifier class_specification 保护指定类的成员,如果此类受到保护他们会保护的更好 -keepclasseswithmembers class_specification 保护指定的类和类的成员,但条件是所有指定的类和类成员是要存在。 -keepnames class_specification 保护指定的类和类的成员的名称(如果他们不会压缩步骤中删除) -keepclassmembernames class_specification 保护指定的类的成员的名称(如果他们不会压缩步骤中删除) -keepclasseswithmembernames class_specification 保护指定的类和类的成员的名称,如果所有指定的类成员出席(在压缩步骤之后) -printseeds filename 列出类和类的成员-keep选项的清单,标准输出到给定的文件 压缩 -dontshrink 不压缩输入的类文件 -printusage filename -whyareyoukeeping class_specification 优化 -dontoptimize 不优化输入的类文件 -assumenosideeffects class_specification 优化时假设指定的方法,没有任何副作用 -allowaccessmodification 优化时允许访问并修改有修饰符的类和类的成员 混淆 -dontobfuscate 不混淆输入的类文件 -printmapping filename -applymapping filename 重用映射增加混淆 -obfuscationdictionary filename 使用给定文件中的关键字作为要混淆方法的名称 -overloadaggressively 混淆时应用侵入式重载 -useuniqueclassmembernames 确定统一的混淆类的成员名称来增加混淆 -flattenpackagehierarchy package_name 重新包装所有重命名的包并放在给定的单一包中 -repackageclass package_name 重新包装所有重命名的类文件中放在给定的单一包中 -dontusemixedcaseclassnames 混淆时不会产生形形色色的类名 -keepattributes attribute_name,. 保护给定的可选属性,例如LineNumberTable, LocalVariableTable, SourceFile, Deprecated, Synthetic, Signature, and InnerClasses。-renamesourcefileattribute string 设置源文件中给定的字符串常量 四、 常见的不能混淆的androidCode1. 不能混淆的情况缺省情况下,proguard 会混淆所有代码,但下面几种是android 代码打包时不能混淆的情况,否则就会这样就会导致程序出错:1) Android系统组件,系统组件有固定的方法被系统调用。2) 被Android Resource 文件引用到的、名字已经固定,也不能混淆。比如Android R 文件中定义的,以及自定义的各种View 等。3) android.app.backup.BackupAgentHelper4) android.preference.Preference5) com.android.vending.licensing.ILicensingService6) Java序列化方法(Parcelable) ,系统序列化需要固定的方法。7) 枚举 ,系统需要处理枚举的固定方法。8) native(本地方法),不能修改本地方法名9) annotations 注释10) 数据库驱动11) 用到反射的地方,比如调用aidl各个开发人员必须检查自己的code 是否用到反射,和其他不能混淆的地方。2. proguard 问题和风险代码混淆后虽然有混淆优化的好处,但是它往往也会带来如下的几点问题:1) 混淆错误,用到第三方库的时候,必须告诉 proguard 不要检查,否则proguard 会报错。2) 运行错误,当code 不能混淆的时候,我们必须要正确配置,否则程序会运行出错,这种情况问题最多。3) 调试苦难,出错了,错误堆栈是混淆后的代码,自己也看不懂。为了防止混淆出问题,你需要熟悉你所有的code ,系统的架构,以及系统和你code的集成的接口,并细心分析。 同时你必须需要一轮全面的测试。 所以混淆也还是有一定风险的。为了避免风险,你可以只是混淆部分关键的代码,但是这样你的混淆的效果也会有所降低。五、 常见问题1. 内存溢出异常主要是proguard在做混淆的时候,吃了很多内存,因此,在运行混淆器的时候,可以增加内存,比如 java -mx512m . 2. 栈溢出异常主要是proguard在做混淆的时候,会对一些代码进行优化,若遇到一些相对复杂的方法时,可能会抛出此异常。对付的办法是增加配置参数-dontoptimize3. ClassNotFoundException当程序访问一个被混淆器移除了的类的时候,可能会碰到类似ClassNotFoundException的异常。这时候,你可以在配置文件中添加-keep这一行来修复这些错误。例如:-keep publicclass-Keep设置有很多可选项和注意地方,所以为了获得更多关于配置信息,强烈推荐你阅读混淆器用户手册。特别有用的有Keep选项综述和举例部分。在混淆器手册问题解决方案部分,介绍了代码在混淆过程中你可能碰到的其他常见问题。4. no such table这类的错误如果项目中含有数据库并且数据库的创建方式为通过实现BaseColumns类来依次创建数据库表的话,那么在混淆之后会出现no such table这类的错误。原因是混淆过程中将系统原有的固定包名混淆了导致编译器找不到该表。解决办法:换数据库的创建方式:直接在继承自SQLiteOpenHelper中执行表格创建即:db.execSQL(DB_CREAT); 这样一来就不会出错了! 5. 引入第三方Jar包时配置在其中加入以下代码:-libraryjars %lib_jar_path%有几个Jar包,便添加几次,如在项目的libs目录下有a.jar,b.jar,c.jar三个Jar包:-libraryjars libs/a.jar-libraryjars libs/b.jar-libraryjars libs/c.jar此外,还有些特殊情况,会令导出发生异常,视具体异常情况而定,比如出现了以下异常:示例1Warning: com.google.android.maps.MapView: cant find referenced class com.android.mkstubs.stubber.MethodStubberWarning: com.google.android.maps.MapView$1: cant find referenced class com.android.mkstubs.stubber.MethodStubber即:Warning: %class_full_name%: cant find referenced class %class_full_name%这种异常情况,需要在proguard.cfg文件中,添加以下代码:-dontwarn %class_full_name% 不检查指定包的文件即可,以上面例子而言,应当如下:-dontwarn com.google.android.maps.*示例2Warning: library class android.content.res.XmlResourceParser extends or implements program class org.xmlpull.v1.XmlPullParserWarning: library class android.view.LayoutInflater depends on program class org.xmlpull.v1.XmlPullParser 这是因为引用的Jar包中含有xmlpull类库,Android系统的类库中已经包含了xmlpull,这样混淆出现了冲突,解决办法是把它里面已存在的和系统库冲突的类去掉,就可以了,产生冲突的类可以从控制台输出中看到。示例3proguard returned with error code 1.See console情况1:Proguard returned with error code 1. See console Error: C:/Documents (系统找不到指定文件) 此类情况有两种:1) 指定的路径中有空格;注意编译脚本(linux环境)不允许路径中出现空格的情况。2) 指定的路径错误。 如果指定的第三方jar的引用路径不对,没有找到这个需要忽略混淆的jar包,就会报这样类似的错误。情况2:Proguard returned with error code 1. See console 异常:java.lang.ArrayIndexOutOfBoundsException解决办法:将proguard-project.txt中的-dontpreverify改成“-dontoptimize”另外对不想混淆的类/方法/变量,可以使用-keep指定,具体参考proguard-project.txt文件写法。6. 打包过程中,提示 Warning: cant find superclass or interface/ Warning: cant find referenced class等警告信息!解决方法:(1) 在配置文件中使用-libraryjars选项来指定代码里引用到的所有库,包括Java运行库。(2) 确保报错的类没有在你的项目中使用到,使用-dontwarn 类名正则表达式屏蔽警告。(3) 使用keep保持第三方内容(jar包)不混淆。以引入android-support-v4.jar包为例,那么在工程打包混淆时,就会出现报错提示。例如提示你:You may need to specify additional library jars (using -libraryjars)。修改progurad.cfg文件,在proguard.cfg里的后面,添加如下内容: java -libraryjars /android-support-v4.jar /指定引入的外部jar包 -dontwarn android.support.v4.* /声明指定包不做引用检查,用来屏蔽警告 -keep class android.support.v4.* *; /声明不混淆的类 -keep public class * extends android.support.v4.* -keep public class * extends android.app.Fragment 然后你再打包看看,应该可以正常生成apk安装包了。出错情况一:类1 cant find referenced class 类2 字面上的意思就是类1找不到类2的引用;它会建议你:You may need to specify additional library jars (using -libraryjars).;需要使用-libraryjars加上项目中使用到的第三方库就OK了。例如:-libraryjars /android-support-v4.jar注意:这里引用方式是当前工程的根目录(也可以配置其他目录),也就是说,你要把第三方jar放到当前目录下,否则就会警告说找不到jar文件!情况二:例如: cant find superclass or interface android.os.Parcelable$ClassLoaderCreator,碰到这样的情况,可以使用-dontwarn com.xx.yy.*,不对错误提出警告。 注意:使用这个方式的话,要确保自己没有用到这个库里面的类!否则就会抛ClassNotFoundException!情况三:在工程中确实用到了该类,采用上面方式还是不行。这个时候就要再增加一项:-keep class com.xx.yy.* *;,让当前类不混淆。小结: 对于引用第三方包的情况,可以采用下面方式避免打包出错: -libraryjars /aaa.jar -dontwarn com.xx.yy.* -keep class com.xx.yy.* *;注意,打包成功后,要将apk包安装到手机上跑跑,确保编译的包没有问题!7. 程序中用到了gson的new typeToken,结果打包成apk发布时,发现抛出异常。解决:第一种:在 proguard.cfg中添加,
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- Module 9 Unit 1 He left school and began work at the age of twelve 教学设计 外研版七年级英语下册
- 2025年中国钢铁耐火材料行业市场分析及投资价值评估前景预测报告
- 2025年中国干湿两用电动剃须刀行业市场分析及投资价值评估前景预测报告
- 2025年中国橄榄叶液体和粉末提取物行业市场分析及投资价值评估前景预测报告
- 2025年中国改性异氰酸酯行业市场分析及投资价值评估前景预测报告
- 2025年地热能源区域供暖技术应用案例分析报告
- 2025年中国氟碳树脂涂料行业市场分析及投资价值评估前景预测报告
- 03 第6讲 力的合成与分解 【答案】听课手册
- 2025年中国风力涡轮齿轮油行业市场分析及投资价值评估前景预测报告
- 第2节 生物对环境的适应和影响教学设计-苏科版生物七年级上册
- 云南省石林县鹿阜中学七年级地理上册 第一章 第四节 地球的公转教案 (新版)商务星球版
- 《路遥人生》读书分享课件
- 以青春之名励青春之志
- 小学数学新旧知识关联
- 第9课 共同弘扬中华传统美德 《中华民族大团结》(初中 精讲课件)
- 万夫一力天下无敌 课件-2023-2024学年高一上学期增强班级凝聚力主题班会
- GB/T 20671.4-2006非金属垫片材料分类体系及试验方法第4部分:垫片材料密封性试验方法
- 灌肠分类、操作及并发症处理
- 《电力工业企业档案分类规则0大类》(1992年修订版)
- (人教版三年级上册)数学时间的计算课件
- 温州医科大学《儿科学》支气管肺炎
评论
0/150
提交评论