Android studio 代码混淆使用 —— ProGuard

时间:2022-07-11 17:17:28

最近项目需要打包测试,想想上次打包测试已经是1年前了,这一年来需求换了好几版,app做了两个都没上线。这次终于要走到最后环节了。那么今天就来学习呀stuido代码混淆的一些知识。

  1. 项目从Eclipse中迁移过来的,两者混淆方案有什么异同
  2. 应该在那个文件中配置混淆规则
  3. 需要配置的内容有哪些

Eclipse代码混淆方法

我们先回顾下 Eclipse 中代码混淆的方法。参考链接

  1. 打开项目目录下的 project.properties 文件,解除以下代码的注释

    proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt

  2. 编写 proguard-project.txt 文件添加自定义的混淆规则。


压缩代码和资源(谷歌官方介绍)

在网上搜索到一些资料后并没有达到自己想要的结果,于是试着Google官方Studio教程寻找答案先给出连接地址。谷歌官方部分中文版studio教程

以下是我自己看完的一些理解:

1 Google对于我们平时所说的代码混淆,更倾向于称作压缩代码+混淆代码。

代码压缩通过 ProGuard 提供,ProGuard 会检测和移除封装应用中未使用的类、字段、方法和属性,包括自带代码库中的未使用项(这使其成为以变通方式解决 64k 引用限制的有用工具)。ProGuard 还可优化字节码,移除未使用的代码指令,以及用短名称混淆其余的类、字段和方法。混淆过的代码可令您的 APK 难以被逆向工程,这在应用使用许可验证等安全敏感性功能时特别有用。

2 要启用通过 ProGuard 实现的代码压缩,请在项目主module下的build.gradle 文件相应的构建类型中添加 minifyEnabled true。

android {
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile(‘proguard-android.txt'),
'
proguard-rules.pro'
}
}
...
}

3 getDefaultProguardFile(‘proguard-android.txt') 方法可从Android SDK tools/proguard/ 文件夹获取默认 ProGuard 设置。这一点与Eclipse混淆的时候一样,与Eclipse不同的是,studio的特殊混淆配置是proguard-rules.pro文件中添加的,而不是在proguard-project.txt中;这里注意两点:

  1. studio工程下这个文件的名字可以更改,但是必须跟build.gradle中 proguardFiles getDefaultProguardFile(‘proguard-android.txt'),
    ** proguard-rules.pro**
    加星号部分对应,否则会在打包的时候报错。

  2. 如果你是从Eclipse中导入到stuido的项目,stuido默认会保留原 proguard-rules.txt文件。在打包的时候并不会报错。但是有些混淆规则并没有应用。所以要手动将上述加星号的文件名改成proguard-rules.txt 即可。

4 以前没有注意构建完成后的build文件夹,其实每次打包完成后,studio会在<module-name>/build/outputs/mapping/release/ 文件夹下生成4个文件,通过这四个文件可以检查混淆的执行情况。

dump.txt
说明 APK 中所有类文件的内部结构。
mapping.txt
提供原始与混淆过的类、方法和字段名称之间的转换。
seeds.txt
列出未进行混淆的类和成员。
usage.txt
列出从 APK 移除的代码。
这些文件保存在 /build/outputs/mapping/release/。

5 经过实际操作发现 studio的压缩方案比之前要优化很多,现在资源压缩可以压缩3M左右。我一个应用打包前有6M打包完了就剩3.4M了,好没成就感。写了一个月代码,就写了3.4M。

ProGuard基础语法和打包配置

同样为了弥补知识漏洞,特意从网上查了些混淆资料。其实这些并不需要记住。因为如果你引用第三方的库。他们会告诉你应该填写什么,但是既然为了学习还是熟悉一边比较好,免得看到一脸懵逼。参考链接,以下内容为连接作者所总结,我只是拿来作为二次查看所用,如有特殊要求,请联系连接作者。

  • libraryjars class_path 应用的依赖包,如android-support-v4
  • keep [,modifier,…] class_specification 不混淆某些类
  • keepclassmembers [,modifier,…] class_specification 不混淆类的成员
  • keepclasseswithmembers [,modifier,…] class_specification 不混淆类及其成员
  • keepnames class_specification 不混淆类及其成员名
  • keepclassmembernames class_specification 不混淆类的成员名
  • keepclasseswithmembernames class_specification 不混淆类及其成员名
  • assumenosideeffects class_specification 假设调用不产生任何影响,在proguard代码优化时会将该调用remove掉。如system.out.println和Log.v等等
  • dontwarn [class_filter] 不提示warnning

具体内容可以参考上述链接,这里说一下常用的几个语法:

  1. 不混淆所有com.clock包下的类 : -keep class 替换为包名全路径(如class com.tencent.mm.opensdk).**
  2. 不混淆某个类和成员变量自定义实体类需要配置该混淆规则-keep class 实体类包名.**{*;}
  3. -dontwarn 包名或类名 打包的时候不提示warnning 注意:有些warning会导致打包失败或者打包完成后不能正常安装,在正式上线前最好进行完整测试。可依据gradle console中所报错误手动配置解除需要解除警告的类。
  4. 另外需要注意,proguard-android.txt文件已经为我们做了几件事情。
    1. 指定不混淆所有的JNI方法
    2. 所有View的子类及其子类的get、set方法都不进行混淆
    3. 不混淆Activity及其子类
    4. 不混淆Enum类型的指定方法
    5. 不混淆R类里及其所有内部static类中的所有static变量字段
    6. 不混淆Parcelable和它的子类,还有Creator成员变量
    7. 不提示兼容库的错误警告

代码混淆实战

  1. 配置开启混淆: minifyEnabled true
 buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
}
  1. 配置proguard-rules.pro文件(此步骤需要根据项目情况配置)

    1.代码中使用了反射

    -keepattributes Signature
    -keepattributes EnclosingMethod

    2.不混淆自定义实体类

    -keep class com.goldenalpha.stock.master.entities.** { *; }

    3.用到了微信登录和分享,支付功能,依据官方文档添加以下混淆规则

    -keep class com.tencent.mm.opensdk.** {
    *;
    }
    -keep class com.tencent.wxop.** {
    *;
    }
    -keep class com.tencent.mm.sdk.** {
    *;
    }

    3.用到了支付宝支付功能,依据官方文档添加以下混淆规则

    -libraryjars libs/alipaySDK-20170309.jar//这个日期要根据所引用的jar包来确定而且,如果gradle配置了依赖此jar,请注释或者清除改行。

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

    4.继承了Serializable接口的类,加上如下规则

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

    5.引用了retrofit 依据官方文档配置混淆规则 这里注意需要加上okHttp和okio也许要配置上

    -dontwarn com.squareup.okhttp.internal.http.*
    -dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
    -keepnames class com.levelup.http.okhttp.** { *; }
    -keepnames interface com.levelup.http.okhttp.** { *; }
    -keepnames class com.squareup.okhttp.** { *; }
    -keepnames interface com.squareup.okhttp.** { *; }

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

    6.引用了Glide图片加载库,配置Glide混淆规则

    -keep public class * implements com.bumptech.glide.module.GlideModule
    -keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {

    **[] $VALUES;
    public *;
    }

    # for DexGuard only

    -keepresourcexmlelements manifest/application/meta-data@value=GlideModule

    7.保持4大组件和Application不被混淆

    -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

以上就是目前项目中所应用的混淆规则,希望大家看完能对混淆有所了解,毕竟不常用。总结一下以备后续只需。