Android Studio 代码混淆(采坑总结)

前言

之前公司app上架一直都是Apk加固 并没有用到代码混淆 现在突然用到了代码混淆?!
为了加深自己的印象 因为我写一篇博客来巩固刚学的知识 如果有错误的地方请指出:

Android Studio 代码混淆

一:什么是代码混淆:
混淆的好处:

  • 代码混淆后阅读性降低,反编译后破译程序难度提高
  • 混淆后字节数减少,减少了应用了体积
    前者只能说有一点作用,后者则需要看代码的数量

混淆的缺点:

  • 混淆后,测试不充分可能导致某些功能不能使用
  • 在博文的最后 我会证明这个缺点 请继续往下看

下面用图和文字来说明流程和配置 一目了然:
首先:
这里写图片描述

如果是导航显示Android模式建议将其改为Project模式 方便浏览格式 找对应的文件也清清楚楚

接着看build.gradle文件说明:(双击可放大原图)
这里写图片描述

上图中的 proguard-android.txt 文件,这是系统默认的混淆文件,具体在../sdk/tools/proguard/ 目录下,其中包含了 android 最基本的混淆,一般不需要改动,我们需要配置的是项目中 app 下的 proguard-rules.pro 文件

混淆规则:

注意:
-keep class com.huawei.** 
-keep class com.meizu.* 
  • 一颗星表示只是保持该包下的类名,而子包下的类名还是会被混淆;
  • 两颗星表示把本包和所含子包下的类名都保持;
proguard-rules.pro配置文件

下面是我的混淆 文件所有内容:注释写的很清楚!~请仔细阅读!! 根据自己情况 配置不同的需求

# 代码混淆压缩比,在0~7之间,默认为5,一般不下需要修改
-optimizationpasses 5

# 混淆时不使用大小写混合,混淆后的类名为小写
# windows下的同学还是加入这个选项吧(windows大小写不敏感)
-dontusemixedcaseclassnames

# 指定不去忽略非公共的库的类
# 默认跳过,有些情况下编写的代码与类库中的类在同一个包下,并且持有包中内容的引用,此时就需要加入此条声明
-dontskipnonpubliclibraryclasses

# 指定不去忽略非公共的库的类的成员
-dontskipnonpubliclibraryclassmembers

# 不做预检验,preverify是proguard的四个步骤之一
# Android不需要preverify,去掉这一步可以加快混淆速度
-dontpreverify

# 有了verbose这句话,混淆后就会生成映射文件
# 包含有类名->混淆后类名的映射关系
# 然后使用printmapping指定映射文件的名称
-verbose
-printmapping priguardMapping.txt

# 指定混淆时采用的算法,后面的参数是一个过滤器
# 这个过滤器是谷歌推荐的算法,一般不改变
-optimizations !code/simplification/artithmetic,!field/*,!class/merging/*

# 保护代码中的Annotation不被混淆
# 这在JSON实体映射时非常重要
-keepattributes *Annotation*

# 避免混淆泛型
# 这在JSON实体映射时非常重要
-keepattributes Signature

# Gson specific classes
-keep class com.google.gson.stream.** { *; }
# Application classes that will be serialized/deserialized over Gson
-keep class com.google.gson.examples.android.model.** { *; }
-keep class com.google.gson.** { *;}

# 抛出异常时保留代码行号
-keepattributes SourceFile,LineNumberTable

# 保留所有的本地native方法不被混淆
-keepclasseswithmembernames class * {
    native <methods>;
}

# 保留了继承自Activity、Application这些类的子类
# 因为这些子类有可能被外部调用
# 比如第一行就保证了所有Activity的子类不要被混淆
-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

#support.v4/v7包不混淆
-keep class android.support.** { *; }
-keep class android.support.v4.** { *; }
-keep public class * extends android.support.v4.**
-keep interface android.support.v4.app.** { *; }
-keep class android.support.v7.** { *; }
-keep public class * extends android.support.v7.**
-keep interface android.support.v7.app.** { *; }
-dontwarn android.support.**    # 忽略警告

# 保留Activity中的方法参数是view的方法,
# 从而我们在layout里面编写onClick就不会影响
-keepclassmembers class * extends android.app.Activity {
    public void * (android.view.View);
}

# 枚举类不能被混淆
-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}

# 保留自定义控件(继承自View)不能被混淆
-keep public class * extends android.view.View {
    public <init>(android.content.Context);
    public <init>(android.content.Context, android.util.AttributeSet);
    public <init>(android.content.Context, android.util.AttributeSet, int);
    public void set*(***);
    *** get* ();
}

# 保留Parcelable序列化的类不能被混淆
-keep class * implements android.os.Parcelable{
    public static final android.os.Parcelable$Creator *;
}

# 不混淆实体类
-keep class com.jxty.app.garden.model.** { *; }

# 保留Serializable 序列化的类不被混淆
-keepclassmembers class * implements java.io.Serializable {
   static final long serialVersionUID;
   private static final java.io.ObjectStreamField[] serialPersistentFields;
   !static !transient <fields>;
   private void writeObject(java.io.ObjectOutputStream);
   private void readObject(java.io.ObjectInputStream);
   java.lang.Object writeReplace();
   java.lang.Object readResolve();
}

# 对R文件下的所有类及其方法,都不能被混淆
-keepclassmembers class **.R$* {
    *;
}

# 对于带有回调函数onXXEvent的,不能混淆
-keepclassmembers class * {
    void *(**on*Event);
}

#EventBus
-keepattributes *Annotation*
-keepclassmembers class ** {
    @org.greenrobot.eventbus.Subscribe <methods>;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }

#Retrofit
# Retain generic type information for use by reflection by converters and adapters.
-keepattributes Signature
# Retain service method parameters.
-keepclassmembernames,allowobfuscation interface * {
    @retrofit2.http.* <methods>;
}
# Ignore annotation used for build tooling.
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement

#OkHttp
-dontwarn okhttp3.**
-dontwarn okio.**
-dontwarn javax.annotation.**
# A resource is loaded with a relative path so the package of this class must be preserved.
-keepnames class okhttp3.internal.publicsuffix.PublicSuffixDatabase

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

#ucrop
-dontwarn com.yalantis.ucrop**
-keep class com.yalantis.ucrop** { *; }
-keep interface com.yalantis.ucrop** { *; }

#android-shape-imageview
-keepattributes *Annotation,Signature
-dontwarn com.github.siyamed.**
-keep class com.github.siyamed.shapeimageview.**{ *; }

# banner 的混淆代码
-keep class com.youth.banner.** {
    *;
}

#仿京东地址选择
-keep class chihane.jdaddressselector.** { *; }
-keep class com.raizlabs.android.dbflow.** { *; }

#BaseRecyclerViewAdapterHelper
-keep class com.chad.library.adapter.** {
*;
}
-keep public class * extends com.chad.library.adapter.base.BaseQuickAdapter
-keep public class * extends com.chad.library.adapter.base.BaseViewHolder
-keepclassmembers  class **$** extends com.chad.library.adapter.base.BaseViewHolder {
     <init>(...);
}

#uCrop
-dontwarn com.yalantis.ucrop**
-keep class com.yalantis.ucrop** { *; }
-keep interface com.yalantis.ucrop** { *; }

#高德定位
-keep class com.amap.api.location.**{*;}
-keep class com.amap.api.fence.**{*;}
-keep class com.autonavi.aps.amapapi.model.**{*;}
#高德搜素
-keep   class com.amap.api.services.**{*;}
#高德2D地图
-keep class com.amap.api.maps2d.**{*;}
-keep class com.amap.api.mapcore2d.**{*;}

-dontwarn com.amap.api.mapcore2d.**

#魔窗
-keep class com.tencent.mm.sdk.** {*;}
-keep class cn.magicwindow.** {*;}
-dontwarn cn.magicwindow.**

#微信sdk
-dontwarn com.tencent.mm.opensdk.**
-keep class com.tencent.mm.opensdk.**{*;}

#支付宝
-keep class com.alipay.android.app.IAlixPay{*;}
-keep class com.alipay.android.app.IAlixPay$Stub{*;}
-keep class com.alipay.android.app.IRemoteServiceCallback{*;}
-keep class com.alipay.android.app.IRemoteServiceCallback$Stub{*;}
-keep class com.alipay.sdk.app.PayTask{ public *;}
-keep class com.alipay.sdk.app.AuthTask{ public *;}
-keep class com.alipay.sdk.app.H5PayCallback {
    <fields>;
    <methods>;
}
-dontwarn com.alipay.android.phone.mrpc.core.**
-keep class com.alipay.android.phone.mrpc.core.** { *; }
-keep class com.alipay.apmobilesecuritysdk.** { *; }
-keep class com.alipay.mobile.framework.service.annotation.** { *; }
-keep class com.alipay.mobilesecuritysdk.face.** { *; }
-keep class com.alipay.tscenter.biz.rpc.** { *; }
-keep class org.json.alipay.** { *; }
-keep class com.alipay.tscenter.** { *; }
-keep class com.ta.utdid2.** { *;}
-keep class com.ut.device.** { *;}

#bugly
-dontwarn com.tencent.bugly.**
-keep public class com.tencent.bugly.**{*;}
-keep class android.support.**{*;}

# 友盟
-dontwarn com.taobao.**
-dontwarn anet.channel.**
-dontwarn anetwork.channel.**
-dontwarn org.android.**
-dontwarn org.apache.thrift.**
-dontwarn com.xiaomi.**
-dontwarn com.huawei.**
-dontwarn com.meizu.**
-dontwarn com.umeng.message.**
-keepattributes *Annotation*
-keep class com.taobao.** {*;}
-keep class com.umeng.message.** {*;}
-keep class org.android.** {*;}
-keep class anet.channel.** {*;}
-keep class com.umeng.** {*;}
-keep class com.xiaomi.** {*;}
-keep class com.huawei.** {*;}
-keep class com.meizu.** {*;}
-keep class org.apache.thrift.** {*;}
-keep class com.alibaba.sdk.android.**{*;}
-keep class com.ut.**{*;}
-keep class com.ta.**{*;}
-keep public class **.R$*{
   public static final int *;
}

#bugly
-dontwarn com.tencent.**
-keep class com.tencent.**{ *; }

# 头条
-dontwarn java.lang.annotation.Annotation
-keep class com.jxty.app.garden.main.headline.** {*;}

编译问题:

配置好了混淆文件以后 就可以编译了 我用图来说明 编译遇到的问题
这里写图片描述

在studio的下方Run面板中会提示 代码混淆遇到的问题 比如第三方更新了版本、或是有些第三方忘了标明不被混淆
根据Warning警告我们看到有一些类找不到 说明不该被混淆的类 我们没有注明!
这里写图片描述

打开proguard-rules.pro 文件在相应的位置加上 相应的需求就可以了

比如我的

  • -dontwarn 不要,表示过滤掉警告
  • -keep 保留,表示不被混淆

解决了所有的Warning基本上就完成了代码混淆了

但是

请注意: 有时候编译器也会有漏掉的警告
解决思路如下:
我们将assembleRelease编译好的APK复制到自己的手机上 安装了跑一遍自己的业务就可以了 ,如果有漏掉的第三方
控件没有注明不被混淆,那么该功能是不能使用的 就是一片空白的情况!!!

我在这次过程中还真就遇到了编译器漏掉的警告 我用了第三方的控件 最后查到是:
这里写图片描述

所以也就有了下面的说明 表示不被混淆,com.jxty.app.garden.main.headline.** {*;}

# 头条
-dontwarn java.lang.annotation.Annotation
-keep class com.jxty.app.garden.main.headline.** {*;}

解决了这个问题 就大功告成了~~!

与君共勉

我要一步一步往上爬
在最高点乘着叶片往前飞
任风吹干流过的泪和汗
我要一步一步往上爬
等待阳光静静看着它的脸
小小的天有大大的梦想
我有属于我的天
任风吹干流过的泪和汗
总有一天我有属于我的天
这里写图片描述

猜你喜欢

转载自blog.csdn.net/Life_s/article/details/81487650