Android代码混淆

一、代码混淆作用:

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

二、开启混淆:

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

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

三、混淆说明:

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

1、常用命令

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

2. 常用规则

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

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

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

  • extends:继承某类的类;

  • implement:实现某接口的类;

  • $:内部类;

  • <init>:所有构造方法;

  • <fields>:所有成员变量;

  • <methods>:所有方法;

  • …:任意参数;

  • 修饰符: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 <init style="box-sizing: border-box;">(); }</init>
不混淆某个类的某个方法-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.** {*;}
#</基础>

#<view相关>
-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 * {
   public void *(android.view.View);
}
#</view相关>

#<Serializable、Parcelable>
-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 *;
}
#</Serializable、Parcelable>

#<R文件>
-keep class **.R$* {
 *;
}
#</R文件>

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

#<natvie>
-keepclasseswithmembernames class * {
    native <methods>;
}
#</natvie>

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

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

#<okhttp3.x>
-dontwarn com.squareup.okhttp3.**
-keep class com.squareup.okhttp3.** { *;}
-dontwarn okio.**
#</okhttp3.x>

#<retrofit2.x>
-dontnote retrofit2.Platform
-dontwarn retrofit2.Platform$Java8
-keepattributes Signature
-keepattributes Exceptions
-dontwarn okio.**
#</retrofit2.x>

#</okhttp3.x>

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

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

#<Gson>
-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.** { *; }
#</Gson>

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

#<Rxjava RxAndroid>
-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;
}
#</Rxjava RxAndroid>

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

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

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

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

#<js>

#</js>

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

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

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

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

六、注意事项:

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

七、参考文章:

  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
  • 4
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值