android 混淆 讲解

转载请标明出处:http://www.jianshu.com/p/1a16eb7fc402

Proguard的作用

proguard除了可以混淆代码,防止被反编译外,还有压缩,优化,预检代码的作用。

在app.gradle文件中的buildTypes里写了一段关于app混淆的语句,先看下

minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'

minifyEnabled true是来设置是否需要混淆
proguardFiles后面跟着两个写着混淆规则的文件,第一个是默认的,第二个是用户自己添加。默认除了proguard-android-optimize.txt之外,还有一个是proguard-android.txt,都在 sdk\tools\proguard 文件夹里,这两个的区别是前一个做过优化,当然添加优化后存在一定的风险,比如不是所有的虚拟机都支持这个优化,具体如下文。

Optimizations: If you don't want to optimize, use the proguard-android.txt configuration file instead of this one, which turns off the optimization flags. Adding optimization introduces certain risks, since for example not all optimizations performed by ProGuard works on all versions of Dalvik. The following flags turn off various optimizations known to have issues, but the list may not be complete or up to date. (The "arithmetic" optimization can be used if you are only targeting Android 2.0 or later.) Make sure you test thoroughly if you go this route.

用户自己添加的混淆规则文件位置是ProjectName\app\proguard-rules.pro,默认的混淆规则在一个大项目里都是不够的,必须要添加很多自定义的混淆规则。

不需要混淆

不混淆的(类、方法等)即名字是不能改变的,不然会出错

  • 反射用到的类不混淆,如一些注解框架需要保证类名方法不变,不然就反射不了。
  • Parcelable和它的子类,还有Creator成员变量不混淆
  • R类里及其所有内部static类中的所有static变量字段不混淆
  • JSON对象类不混淆,不然无法将JSON解析成对应的对象。
  • 使用第三方开源库或者引用其他第三方的SDK包时,需要在混淆文件中加入对应的混淆规则
  • 有用到WebView的Js调用也需要保证写的接口方法不混淆
  • JNI方法不混淆
  • ……

ProGuard的常用语法

-libraryjars class_path 应用的依赖包,如Android-support-v4
-keep [,modifier,...] class_specification 不混淆某些类
-keepclassmembers [,modifier,...] class_specification 不混淆类的成员
-keepclasseswithmembers [,modifier,...] class_specification 不混淆类及其成员
-keepnames class_specification 不混淆类及其成员名
-keepattributes {attribute_name,...} 不混淆给定的可选属性
-keepclassmembernames class_specification 不混淆类的成员名
-keepclasseswithmembernames class_specification 不混淆类及其成员名
-assumenosideeffects class_specification 假设调用不产生任何影响,在proguard代码优化时会将该调用remove掉。如Log等等
-dontwarn [class_filter] 不提示warnning
more

常用代码

  • 不混淆某类的构造方法,需指定构造函数的参数类型,如JSONObject
-keepclassmembersclass cn.trinea.android.common.service.impl.ImageCache{
   public(int);
}
  • 不混淆某个包所有类或某个类class、某个接口interface, 不混淆指定类则把**换成类名
-keep class com.facebook.**
-keep class cn.trinea.android.common.**{ *;}
  • 不混淆指某个方法,*可换成指定的方法或类名
-keepclassmembersclass cn.trinea.android.common.service.impl.ImageCache{
   public boolean get(java.lang.String,android.view.View);
}
  • 不混淆Parcelable的子类,防止android.os.BadParcelableException
-keep class *implements android.os.Parcelable{
  public static final android.os.Parcelable$Creator*;
}
  • 添加android-support-v4.jar依赖包
-libraryjars  libs/android-support-v4.jar
-dontwarn android.support.v4.**    
-keep class android.support.v4.**{ *;}  
-keep interface android.support.v4.app.**{ *;}
  • proguard与log level结合解决debug模式Log问题,表示Log.d和Log.v代码无副作用,在proguard时会被从源码中remove掉,这样release模式(正式发布)就不会打印日志了,而debug模式(平常调试)照常打印。
-assumenosideeffects class android.util.Log{
    public static ***d(...);
    public static ***v(...);
}

more

映射

mapping.txt 列出了原始的类,方法和字段名与混淆后代码间的映射。这个文件很重要,当你从release版本中收到一个bug报告时,可以用它来翻译被混淆的代码。
mapping文件在 \app\build\outputs\mapping\release

特别推荐以下几篇 参考资料:

  1. http://blog.csdn.net/chen930724/article/details/49687067
  2. http://www.trinea.cn/android/proguard-grammar/
  3. http://blog.csdn.net/yunyu5120/article/details/13024359
  4. 官网

你可能感兴趣的:(android 混淆 讲解)