转载请标明出处:http://blog.csdn.net/xx326664162/article/details/49250203
文章出自:[薛瑄的博客](http://blog.csdn.net/xx326664162)
你也可以查看我的其他同类文章,也会让你有一定的收货!
参考:
http://blog.csdn.net/zuiwuyuan/article/details/48552701
ProGuard
这个ProGuard工具可以通过删除未使用的代码和重命名类、字段和方法与语义模糊的名字来 收缩、优化和混淆你的代码。这个结果导致你生成一个更小型号的 .apk 文件,这样会使别人反向逆推工程更加困难。 因为 ProGuard 让你的应用程序的还原工程更加困难。这个对你而言是十分有用的,当你利用这个应用特点来帮助当你的程序度过一些安全和敏感的检测当你正对你的程序授权时。
ProGuard是集成到Android 开发系统中的,因此你不必手动调用这个应用。ProGuard 只有在你编译运行程序的时候才运作,因此当你在调试模式下编译你的程序的时候,你不需要处理混淆代码。是否有 ProGuard 运行是可以完全由你有选择的,但强烈推荐你去运行它。
混淆
现在网上关于反编译的博客很多了,我在此就不多做介绍了,放上个传送门传送门
那么我们已经知道了反编译是如此的简单,我们总不希望自己辛苦写的代码被如此轻易的反编译走,而且这样有可能对公司的服务器留下被攻击的隐患,那么我们就可以使用混淆来保护我们所写的代码
Android studio混淆和Eclipse差不多是大同小异的。
名称 | 作用 |
---|---|
minifyEnabled | 是否开启混淆 |
shrinkResources | 去除无用的resource文件 |
proguardFiles getDefaultProguardFile | 加载混淆配置文件 |
如果按照默认的混淆规则很有可能你的程序会报错,因为混淆了一些方法所以程序运行期间无法找到该方法。所以我们应该自定义一些规则在默认的的混淆文件proguard-project.txt或proguard-rules.pro中,
-optimizationpasses 5 # 指定代码的压缩级别 -dontusemixedcaseclassnames # 是否使用大小写混合 -dontskipnonpubliclibraryclasses # 是否混淆第三方jar -dontpreverify # 混淆时是否做预校验 -verbose # 混淆时是否记录日志 -optimizations !code/simplification/arithmetic,!field/*,!class/merging/* # 混淆时所采用的算法 -keep public class * extends android.app.Fragment -keep public class * extends android.app.Activity # 保持哪些类不被混淆 -keep public class * extends android.app.Application # 保持哪些类不被混淆 -keep public class * extends android.app.Service # 保持哪些类不被混淆 -keep public class * extends android.content.BroadcastReceiver # 保持哪些类不被混淆 -keep public class * extends android.content.ContentProvider # 保持哪些类不被混淆 -keep public class * extends android.app.backup.BackupAgentHelper # 保持哪些类不被混淆 -keep public class * extends android.preference.Preference # 保持哪些类不被混淆 -keep public class com.android.vending.licensing.ILicensingService # 保持哪些类不被混淆 -keepclasseswithmembernames class * { # 保持 native 方法不被混淆 native <methods>; } -keepclasseswithmembers class * { # 保持自定义控件类不被混淆 public <init>(android.content.Context, android.util.AttributeSet); } -keepclasseswithmembers class * { public <init>(android.content.Context, android.util.AttributeSet, int); # 保持自定义控件类不被混淆 } -keepclassmembers class * extends android.app.Activity { # 保持自定义控件类不被混淆 public void *(android.view.View); } -keepclassmembers enum * { # 保持枚举 enum 类不被混淆 public static **[] values(); public static ** valueOf(java.lang.String); } -keep class * implements android.os.Parcelable { # 保持 Parcelable 不被混淆 public static final android.os.Parcelable$Creator *; }
以上是最基础的配置,几乎每个项目都需要进行这些地方的混淆(或保持不混淆)
-dontoptimize #不优化输入的类文件,(如果没有使用该语句,说明要优化,就要指定相关的优化语句,如以下两条语句) -dontskipnonpubliclibraryclasses #不去忽略非公共的库类 -keepattributes Annotation #保护注解 -keepclasseswithmembernames class com.yuantel.meeting.entity.**{*;} #这句话是指entity包下所有的类及其成员都不混淆;-keep public class * extends android.support.v4.app.Fragment #如果有引用v4包可以添加下面这行 -ignorewarning #忽略警告 -dump class_files.txt #记录生成的日志数据,gradle build时在本项目根目录输出 apk 包内所有 class 的内部结构 -printmapping mapping.txt #混淆前后的映射 (我是在使用了这条语句后,就在build\outputs\mapping\你的项目名\release\文件夹下,出现了dump.txt, mapping.txt, seeds.txt, usage.txt)-printseeds seeds.txt #未混淆的类和成员 -printusage unused.txt (dump.txt) #列出从 apk 中删除的代码
上面这些是一些可能会用到的配置
mapping文件
-printmapping mapping.txt
mapping.txt 列出了原始的类,方法和字段名与混淆后代码间的映射。这个文件很重要,当你从release版本中收到一个bug报告时,可以用它来翻译被混淆的代码。这里下载符号表工具。mapping.txt文件在module的根目录下,即使制定了目录也会在module的根目录下。
第三方库 混淆配置
1.如果使用了Gson之类的工具要使JavaBean类不被混淆。
2.如果使用了自定义控件那么要保证它们不参与混淆。
3.如果使用了枚举要保证枚举不被混淆。
4.对第三方库中的类不进行混淆
a.混淆时保护引用的第三方jar包
如:-libraryjars libs/baidumapapi_v3_2_0.jar #保护引用的第三方jar包不被混淆
注意:在使用Eclipse+ADT时需要加入-libraryjars libs/...,
如果你是使用Android Studio开发的项目则不需要加入libs包中的jar包,这是因为,通过Android Studio进行混淆代码时,默认已经将 lib目录中的 jar 都已经添加到打包脚本中,所以不需要再次手动添加,否则会出现“ java.io.IOException: The same input jar is specified twice” 错误。
b.混淆时保护第三方jar包中的类不被混淆
如:-keep class com.baidu.** { *; } #保持com.baidu.**这个包里面的所有类和所有方法不被混淆。
-dontwarn com.baidu.** #让ProGuard不要警告找不到com.baidu.**这个包里面的类的相关引用
因为你在项目中,总会不可避免的引用第三方的library库或是jar包,那,如果你不能够正确的混淆第三方的资源,可能会导致你的应用无法使用。(我就因为忘了配置Gson相关的混淆,导致页面一直没有数据显示,蛋疼的一笔)。
贴出我项目中关于第三方的混淆部分:
使用了fastjson 混淆配置
可参考这里配置,这篇博客我未亲测:http://blog.csdn.net/wangjintao1988/article/details/17119249
-keepclassmembers class * implements java.io.Serializable { static final long serialVersionUID; private static final java.io.ObjectStreamField[] serialPersistentFields; private void writeObject(java.io.ObjectOutputStream); private void readObject(java.io.ObjectInputStream); java.lang.Object writeReplace(); java.lang.Object readResolve();}-keep class com.alibaba.fastjson.** { *; } -keepclassmembers class * { public <methods>; }-keep public class * extends android.view.View { public <init>(android.content.Context); public <init>(android.content.Context, android.util.AttributeSet); public <init>(android.content.Context, android.util.AttributeSet, int); public void set*(...); public void get*(...);}-dontskipnonpubliclibraryclassmembers-dontskipnonpubliclibraryclasses-keepattributes Signature #这条语句,很多人说是使用Gson,配置时使用的,但是我亲测,fastjson不使用这条会出错
枚举类 混淆配置
#保持枚举 enum 类不被混淆 如果混淆报错,建议直接使用上面的 -keepclassmembers class * implements java.io.Serializable即可 -keepclassmembers enum * { public static **[] values(); public static ** valueOf(java.lang.String); }
再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow