一 为什么要混淆
java源代码通过编译成字节码文件存储在.class文件中,字节码文件中包含了变量名,方法名等信息,而程序是通过这些名称来访问变量和方法的,这些信息很容易反编译成java源代码,所以需要通过proguard来对java字节码进行混淆,而混淆前后的代码具有相同的功能。
Proguard混淆技术可以压缩,优化我们的apk,同时可以混淆我们的代码,主要作用是可以移除代码中无用的类,字段,属性和方法同时混淆类,字段,属性和方法的命名,通过压缩优化移除最终可以让apk文件体积更小,即使apk被反编译,代码中也是a,b,c,d这些无意义的名称。
二 哪些代码不能混淆
1 实现了序列号接口的java类不能被混淆,否则反序列化会失败。
2 Android系统组件比如Activity,Fragment,系统组件有固定的方法被系统调用。
3 自定义View,Bean类,Event,native方法,还有枚举类型等,不能被混淆。
4 用到反射的地方。比如R文件不能被混淆。
......
三 处理不能被混淆的小技巧
工程里很多需要 keep 的类和方法(比如一些 bean 类和 event 类)都是直接写在 Proguard 里的,很容易遗漏和出错,比如漏加了某个类的混淆规则或者类的路径更改但忘记修改混淆规则等。如
-keep class com.xxxx.timer.abstraction.bean.** { *; }
-keep class com.xxxx.timer.waterImpl.bean.** { *; }
-keep class com.xxxx.stencil.event.** { *; }
不想被混淆的代码,都需要像上面这样写,比较繁琐。
所以看看 Keep Annotation小技巧,用法如下:
在Proguard里加上:
#keep
-keep,allowobfuscation @interface android.support.annotation.Keep
# Do not strip any method/class that is annotated with @Keep
-keep @android.support.annotation.Keep class *
-keepclassmembers class * { @android.support.annotation.Keep *; }
接下来就可以为所欲为的实用@Keep了,彻底摆脱繁琐的混淆规则。
例子
一些需要 json 解析的 bean 类。
@Keep
public class LoginBean {
public String accout;
public String password;
}
EventBus 中使用到的 event 类。
@Keep
public class NoticeChange { }
是不是很方便O(∩_∩)O。