您的位置:首页 > 移动开发 > Android开发

厉害了!让你一看就会的android代码混淆

2017-09-01 10:16 260 查看
前言:混淆是上线前一个倍儿重要的环节,我们不想自己辛辛苦苦开发的应用被别人反编译出来,并且公司也不允许这样的事情发生。再则,现在面试基本都要求独立开发,不知道怎么混淆是不是很尴尬。那么就让我们看看怎么写混淆文件。当然我使用的是Android studio,还是2.3的。Android Studio自身集成Java语言的ProGuard作为压缩,优化和混淆工具,配合Gradle构建工具使用很简单。后面会有一篇对ProGuard详解的笔记,我们先看一下如何给一个项目加混淆。

一、具体步骤

1.在工程应用目录的gradle文件设置minifyEnable为true

android {
...
buildTypes {
release {
minifyEnabled true
zipAlignEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
发布应用的时候应该设置zipAlignEnabled为true,可以让安装包中的资源按4字节对齐,可以减少应用在运行时的内存消耗。像Google Play强制要求开发者上传的应用必须是经过zipAlign的

2.到项目中的proguard-rules.pro文件编写混淆规则

不要问我这个文件在哪,我不会告诉你在项目gradle文件下面。打开你会看到好多注解的东西,建议仔细看看,有对一些指令的解释,我没过四级都能看懂!

这是找到的一个模板,同时也是我在实际项目中使用的,拿走不谢。

#---------------------------------基本指令区----------------------------------
-optimizationpasses 5
-dontskipnonpubliclibraryclassmembers
-printmapping proguardMapping.txt
-optimizations !code/simplification/cast,!field/*,!class/merging/*
-keepattributes *Annotation*,InnerClasses
-keepattributes Signature
-keepattributes SourceFile,LineNumberTable

#---------------------------------默认保留区---------------------------------
-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 * extends android.view.View
-keep public class com.android.vending.licensing.ILicensingService
-keep class android.support.** {*;}

-keep public class * extends android.view.View{
*** get*();
void set*(***);
public <init>(android.content.Context);
public <init>(android.content.Context, android.util.AttributeSet);
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet);
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-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 **.R$* {
*;
}
-keepclassmembers class * {
void *(**On*Event);
}
#---------------------------------webview------------------------------------
-keepclassmembers class fqcn.of.javascript.interface.for.Webview {
public *;
}
-keepclassmembers class * extends android.webkit.WebViewClient {
public void *(android.webkit.WebView, java.lang.String, android.graphics.Bitmap);
public boolean *(android.webkit.WebView, java.lang.String);
}
-keepclassmembers class * extends android.webkit.WebViewClient {
public void *(android.webkit.WebView, jav.lang.String);
}

#---------------------------------1.实体类---------------------------------
-keep class 你的实体类所在的包.** {
*;
}
如我的包com.academy.english.listen.bean
我的混淆为 -keep class com.academy.english.listen.bean.** {
*;
}
---------------------------------2.第三方包-------------------------------
#glide
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public class * extends com.bumptech.glide.AppGlideModule
-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {

4000
**[] $VALUES;
public *;
}

#eventBu
-keepattributes *Annotation*
-keepclassmembers class ** {
@org.greenrobot.eventbus.Subscribe <methods>;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }
# Only required if you use AsyncExecutor
-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {
<init>(java.lang.Throwable);
}

#litepal
-keep class org.litepal.** {*;}
-keep class * extends org.litepal.crud.DataSupport { *;}

#okhttp
-dontwarn okhttp3.**
-keep class okhttp3.**{*;}

#okio
-dontwarn okio.**
-keep class okio.**{*;}

#okgo
-dontwarn com.lzy.okgo.**
-keep class com.lzy.okgo.**{*;}

#okserver
-dontwarn com.lzy.okserver.**
-keep class com.lzy.okserver.**{*;}

#fastjson
-keepattributes Signature
-dontwarn com.alibaba.fastjson.**
-keep class com.alibaba.fastjson.**{*; }

#butterknife
-keep class butterknife.** { *; }
-dontwarn butterknife.internal.**
-keep class **$$ViewBinder { *; }
-keepclasseswithmembernames class * {
@butterknife.* <fields>;
}
-keepclasseswithmembernames class * {
@butterknife.* <methods>;
}

保留区中在项目中没有用到的可以删掉;
修改自己项目中第三方库混淆。查看build.gradle文件看使用了那种三方库,然后去github或者官网上将混淆粘下来就行。用浏览器搜应该也能搜到。我这里就当是笔记下来了,以后用到直接粘,是不是很机智。


二、基本指令的含义:

-optimizationpasses 5   代码混淆的压缩比例,值在0-7之间
-dontskipnonpubliclibraryclassmembers   指定不去忽略非公共的库的类的成员
-printmapping proguardMapping.txt   生成原类名和混淆后的类名的映射文件
-optimizations !code/simplification/cast,!field/*,!class/merging/*  指定混淆是采用的算法
-keepattributes *Annotation*,InnerClasses   不混淆Annotation和内部类
-keepattributes Signature   不混淆泛型
-keepattributes SourceFile,LineNumberTable  这个本身有解释,抛出异常时保留代码行号


写在最后:

在面试中常碰到的问题,那些不需要混淆,面试官也是有点区分你到底做没做过的意思。其实就是我们的保留区,将保留下来的说出来就OK了

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);
}

还有一点:ProGuard混淆的是Android项目里面的java代码,仅仅是java代码。它是无法混淆资源文件drawable、xml等,所以资源文件也是不会混淆的。想对ProGuard有更深一步了解看下面一篇文章。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: