Android代码混淆

一、代码混淆作用:

  1. 防止反编译;
  2. 精简编译后的apk文件大小;

二、开启混淆:

  • 在项目的build.gradle中开启混淆:

Android代码混淆_第1张图片

  • 将minifyEnabled的值改为true即开启:其中debug为测试版本,release为发布版本

Android代码混淆_第2张图片

三、混淆说明:

开启混淆后Android会用自带的混淆进行代码混淆,如在安装Android SDK的目录下的proguard-android.txt或proguard-android-optimize.txt文件为默认混淆文件。对于自己定义的混淆需要在proguard-rules.pro文件中进行配置:

Android代码混淆_第3张图片

1、常用命令

命令 作用
-keep 防止该类所有内容被移除或重命名
-keepnames 防止类和成员被重命名
-keepclassmembers 防止成员被移除或者被重命名
-keepclasseswithmembers 防止拥有该成员的类和成员被移除或者被重命名
-keepclasseswithmembernames 防止拥有该成员的类和成员被重命名

2. 常用规则

  • 类:需要使用完全限定名;

  • *:通配符,任意字符串,不包含包名分隔符(.);

  • **:通配符,任意字符串,包含包名分隔符(.);

  • extends:继承某类的类;

  • implement:实现某接口的类;

  • $:内部类;

  • :所有构造方法;

  • :所有成员变量;

  • :所有方法;

  • …:任意参数;

  • 修饰符:public private protected

3. 例子

含义 指令语句
不混淆某个类 -keep public class packageName.className{ *; }
不混淆某个包的所有类 -keep class packageName.**{ *; }
不混淆某个类的子类 -keep public class * extends packageName.className{ *; }
不混淆某个接口的子类 -keep public class * implements packageName.className{ *; }
不混淆某个类的构造方法 -keepclassmembers class packageName.className{ public (); }
不混淆某个类的某个方法 -keepclassmembers class packageName.className{ public void methodName(…); }
不混淆某个类的内部类 -keep class packageName.className$*{ *; }

四、自定义混淆模板:

将报错的或者自己不需要的删除即可,然后在最后添加自己不需要混淆的代码:

#---------这里提供一份这个lib中最好不要混淆的地方,前边的配置都差不多,主要是第三方包以及其他不需要混淆的代码----
#---------------------------------基本指令以及一些固定不混淆的代码--开始--------------------------------

#<基本指令>
-optimizationpasses 5
-dontskipnonpubliclibraryclassmembers
-optimizations !code/simplification/cast,!field/*,!class/merging/*
-keepattributes *Annotation*,InnerClasses
-keepattributes Signature
-keepattributes SourceFile,LineNumberTable
#忽略警告
-ignorewarning
#记录生成的日志数据,gradle build时在本项目根目录输出apk 包内所有 class 的内部结构
-dump class_files.txt
#未混淆的类和成员
-printseeds seeds.txt
#列出从 apk 中删除的代码
-printusage unused.txt
#混淆前后的映射
-printmapping mapping.txt
#

#<基础>
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.support.multidex.MultiDexApplication
-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 (android.content.Context);
    public (android.content.Context, android.util.AttributeSet);
    public (android.content.Context, android.util.AttributeSet, int);
}
-keepclasseswithmembers class * {
    public (android.content.Context, android.util.AttributeSet);
    public (android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers class * {
   public void *(android.view.View);
}
#

#
-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 public class * implements java.io.Serializable {*;}

-keep class * implements android.os.Parcelable {
  public static final android.os.Parcelable$Creator *;
}
#

#
-keep class **.R$* {
 *;
}
#

#
-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}
#

#
-keepclasseswithmembernames class * {
    native ;
}
#

#---------------------------------基本指令以及一些固定不混淆的代码--结束-----------

#---------------------------------第三方包--开始-------------------------------

#
-dontwarn com.squareup.okhttp3.**
-keep class com.squareup.okhttp3.** { *;}
-dontwarn okio.**
#

#
-dontnote retrofit2.Platform
-dontwarn retrofit2.Platform$Java8
-keepattributes Signature
-keepattributes Exceptions
-dontwarn okio.**
#

#

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

#
-keepattributes *Annotation*
-keepclassmembers class ** {
    @org.greenrobot.eventbus.Subscribe ;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }
-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {
    (java.lang.Throwable);
}
#

#
-keep class com.google.gson.** {*;}
-keep class com.google.**{*;}
-keep class sun.misc.Unsafe { *; }
-keep class com.google.gson.stream.** { *; }
-keep class com.google.gson.examples.android.model.** { *; }
#

#
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
  **[] $VALUES;
  public *;
}
#

#
-dontwarn rx.*
-dontwarn sun.misc.**

-keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* {
   long producerIndex;
   long consumerIndex;
}

-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueProducerNodeRef {
    rx.internal.util.atomic.LinkedQueueNode producerNode;
}

-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueConsumerNodeRef {
    rx.internal.util.atomic.LinkedQueueNode consumerNode;
}
#

#----------------------------------第三方包--结束--------------------------

#---------------------------------一些不要混淆的代码--开始-------------------

-keep class net.arvin.afbaselibrary.nets.** { *; }
-keep class net.arvin.afbaselibrary.data.** { *; }

#<反射>
-keep class net.arvin.afbaselibrary.nets.BaseNet{*;}
#

#

#

#<自定义View的类>
-keep class net.arvin.afbaselibrary.ui.views.** {*;}
#

#---------------------------------一些不要混淆的代码--结束-------------------

五、编译aar文件或apk文件:

因为我们提供给别人的一般都是release版本的库,所以要在build.gradle中开启release版代码混淆,配置好混淆规则后在Android studio的Terminal界面输入:gradlew assembleRelease回车进行编译打包,如果编译失败则检查配置的混淆规则。成功后即可得到混淆后的aar或apk文件:

Android代码混淆_第4张图片

六、注意事项:

混淆时对外暴露的接口层不能混淆,实体类不能混淆。

七、参考文章:

  1. https://www.jianshu.com/p/252759ca6042
  2. https://blog.csdn.net/github_30662571/article/details/70921710
  3. http://www.androidchina.net/8367.html
  4. https://www.jianshu.com/p/d1cbe2fdb82c

你可能感兴趣的:(Android,代码混淆)