Android 混杂及反编译东西Jadx
Android Studio本身集成Java言语的ProGuard作为紧缩,优化和混杂东西,合作Gradle构建东西运用很简单,只需要在工程使用目录的gradle文件中设置minifyEnabled为true即可。然后咱们就能够到proguard-rules.pro文件中参加咱们的混杂规矩了。
android {
...
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' }
}
}
以上示例代码表明对release版本就行混杂处理。下面咱们先来简介下ProGuard的三大效果,并简要阐明下它们常用的指令。
ProGuard效果
紧缩(Shrinking):默许敞开,用以减小使用体积,移除未被运用的类和成员,并且会在优化动作履行之后再次履行(由于优化后可能会再次露出一些未被运用的类和成员)。
-dontshrink 封闭紧缩
优化(Optimization):默许敞开,在字节码等级履行优化,让使用运转的更快。
-dontoptimize 封闭优化
-optimizationpasses n 表明proguard对代码进行迭代优化的次数,Android一般为5
混杂(Obfuscation):默许敞开,增大反编译难度,类和类成员会被随机命名,除非用keep维护。
-dontobfuscate 封闭混杂
混杂后默许会在工程目录app/build/outputs/mapping/release下生成一个mapping.txt文件,这便是混杂规矩,咱们能够根据这个文件把混杂后的代码反推回源本的代码,所以这个文件很重要,注意维护好。原则上,代码混杂后越乱越无规律越好,但有些当地咱们是要避免混杂的,不然程序运转就会犯错,所以就有了下面咱们要教大家的,怎么让自己的部分代码避免混杂从而避免犯错。
根本规矩
先看如下两个比较常用的指令,很多童鞋可能会比较迷惑以下两者的差异。
-keep class cn.hadcn.test.**
-keep class cn.hadcn.test.*
一颗星表明仅仅坚持该包下的类名,而子包下的类名还是会被混杂;两颗星表明把本包和所含子包下的类名都坚持;用以上办法坚持类后,你会发现类名尽管未混杂,但里边的具体办法和变量命名还是变了,这时假如既想坚持类名,又想坚持里边的内容不被混杂,咱们就需要以下办法了
-keep class cn.hadcn.test.* {*;}
在此基础上,咱们也能够运用Java的根本规矩来维护特定类不被混杂,比如咱们能够用extend,implement等这些Java规矩。如下例子就避免一切继承Activity的类被混杂
-keep public class * extends android.app.Activity
假如咱们要保存一个类中的内部类不被混杂则需要用$符号,如下例子表明坚持ScriptFragment内部类JavaScriptInterface中的一切public内容不被混杂。
-keepclassmembers class cc.ninty.chat.ui.fragment.ScriptFragment$JavaScriptInterface {
public *;
}
再者,假如一个类中你不希望坚持全部内容不被混杂,而仅仅希望维护类下的特定内容,就能够运用
<init>; //匹配一切构造器
<fields>; //匹配一切域
<methods>; //匹配一切办法办法
你还能够在或前面加上private 、public、native等来进一步指定不被混杂的内容,如
-keep class cn.hadcn.test.One {
public <methods>;
}
表明One类下的一切public办法都不会被混杂,当然你还能够参加参数,比如以下表明用JSONObject作为入参的构造函数不会被混杂
-keep class cn.hadcn.test.One {
public <init>(org.json.JSONObject);
}
有时候你是不是还想着,我不需要坚持类名,我只需要把该类下的特定办法坚持不被混杂就好,那你就不能用keep办法了,keep办法会坚持类名,而需要用keepclassmembers ,如此类名就不会被坚持,为了便于对这些规矩进行理解,官网给出了以下表格
保存 | 避免被移除或许被重命名 | 避免被重命名 |
---|---|---|
类和类成员 | -keep | -keepnames |
仅类成员 | -keepclassmembers | -keepclassmembernames |
假如具有某成员,保存类和类成员 | -keepclasseswithmembers | -keepclasseswithmembernames |
移除是指在紧缩(Shrinking)时是否会被删去。以上内容时混杂规矩中需要要点把握的,了解后,根本一切的混杂规矩文件你应该都能看懂了。再合作以下几点注意事项,敞开你为自己代码,实现混杂规矩之旅吧。
注意事项
1,jni办法不可混杂,由于这个办法需要和native办法坚持一致;
-keepclasseswithmembernames class * { # 坚持native办法不被混杂
native <methods>;
}
2,反射用到的类不混杂(不然反射可能出现问题);
3,AndroidMainfest中的类不混杂,所以四大组件和Application的子类和Framework层下一切的类默许不会进行混杂。自定义的View默许也不会被混杂;所以像网上贴的很多排除自定义View,或四大组件被混杂的规矩在Android Studio中是无需参加的;
4,与服务端交互时,运用GSON、fastjson等结构解析服务端数据时,所写的JSON对象类不混杂,不然无法将JSON解析成对应的对象;
5,运用第三方开源库或许引证其他第三方的SDK包时,假如有特别要求,也需要在混杂文件中参加对应的混杂规矩;
6,有用到WebView的JS调用也需要确保写的接口办法不混杂,原因和第一条相同;
7,Parcelable的子类和Creator静态成员变量不混杂,不然会产生Android.os.BadParcelableException异常;
-keep class * implements Android.os.Parcelable { # 坚持Parcelable不被混杂
public static final Android.os.Parcelable$Creator *;
}
8,运用enum类型时需要注意避免以下两个办法混杂,由于enum类的特殊性,以下两个办法会被反射调用,见第二条规矩。
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
写在最后
发布一款使用除了设minifyEnabled为ture,你也应该设置zipAlignEnabled为true,像Google Play强制要求开发者上传的使用必须是通过zipAlign的,zipAlign能够让安装包中的资源按4字节对齐,这样能够削减使用在运转时的内存耗费。
android 反编译东西Jadx
github.com/skylot/jadx
检查源码东西
Source Insight