在Android Studio中,实现APK的混淆是一件简单的事情。本文将介绍如何在AS中进行混淆操作。
首先,需要在gradle文件中设置minifyEnabled为true。具体操作如下:
```java
android {
buildTypes {
release {
minifyEnabled true
zipAlignEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
```
注意!一般我们还会设置zipAlignEnabled为true,一方面是关于有些应用市场上传需要,一方面是可以减少应用的运行消耗。
设置好之后就可以去proguard-rules.pro文件中加入我们的混淆规则了。下面就是一些常用混淆规则和ProGuard3大功能。
一、ProGuard功能
1. 压缩(Shrinking):默认开启,用以减小应用体积,移除未被使用的类和成员,并且会在优化动作执行之后再次执行(因为优化后可能会再次暴露一些未被使用的类和成员)。
-dontshrink 关闭压缩
2. 优化(Optimization):默认开启,在字节码级别执行优化,让应用运行的更快。
-dontoptimize 关闭优化 -optimizationpasses n 表示proguard对代码进行迭代优化的次数,Android一般为5
3. 混淆(Obfuscation):默认开启,增大反编译难度,类和类成员会被随机命名,除非用keep保护。
-dontobfuscate 关闭混淆
二、混淆规则
1. keep前缀就是表示保持不变,对于下面2种情况:
-keep class cn.hadcn.test.** -keep class cn.hadcn.test.*
一颗星表示只是保持该包下的类名,而子包下的类名还是会被混淆;两颗星表示把本包和所含子包下的类名都保持。(注意类名没混淆,但里面的方法和成员会混淆)
-keep class cn.hadcn.test.* {*;}
这是保持类名,又保持里面的内容不被混淆的写法。
在Android项目中,我们可以通过ProGuard配置文件来实现代码混淆。以下是一些关于ProGuard配置的注意事项:
1. 通过使用`extend`关键字,可以让继承该类的不被混淆。需要注意的是,AndroidManifest中的类不进行混淆,因此四大组件和Application的子类以及Framework层下的所有类默认不会进行混淆。自定义的View默认也不会被混淆。因此,像网上贴的很多排除自定义View或四大组件被混淆的规则在Android Studio中是无需加入的。
2. 如果我们要保留一个类中的内部类不被混淆,则需要用$符号。例如,下面的代码表示保持ScriptFragment内部类JavaScriptInterface中的所有public内容不被混淆。
```proguard
-keepclassmembers class cc.ninty.chat.ui.fragment.ScriptFragment$JavaScriptInterface { public *; }
```
3. 如果希望类里面的构造方法、成员变量、方法不被混乱,可以使用`-keepclassmembers`选项。例如:
```proguard
-keepclassmembers class cc.ninty.chat.ui.fragment.ScriptFragment$JavaScriptInterface { public *; }
```
你还可以在或前面加上private、public、native等来进一步指定不被混淆的内容,如:
```proguard
-keep class cn.hadcn.test.One { public <methods>; }
```
4. 使用`keepclassmembers`方法可以使类名不被混淆,从而保持固定内容不被混淆。
最后,有一些内容是不能被混淆的,否则会导致应用崩溃:
1. JNI方法不可混淆,因为这个方法需要和native方法保持一致。例如:
```proguard
-keepclasseswithmembernames class * { # 保持native方法不被混淆 native <methods>; }
```
同理,有用到WebView的JS调用也需要保证写的接口方法不混淆。
请根据以下内容完成重构,并保持段落结构:
2. 当与服务端交互时,使用GSON、fastjson等框架解析服务端数据。如果在编写的JSON对象类中没有使用混淆规则进行混淆,那么将无法将JSON解析成对应的对象。
3. 如果使用第三方开源库或者引用其他第三方的SDK包,并且有特别的要求,也需要在混淆文件中加入对应的混淆规则。
4. 在Parcelable的子类和Creator静态成员变量中不要混淆,否则会产生Android.os.BadParcelableException异常。以下是一个示例混淆规则:
```java
-keep class * implements Android.os.Parcelable {
public static final Android.os.Parcelable$Creator *;
}
```
5. 在使用enum类型时,需要注意避免以下两个方法混淆,因为enum类的特殊性,这两个方法会被反射调用。以下是示例混淆规则:
```java
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
```