Android编译优化之混淆配置

news2024/10/5 17:25:37

Android编译优化之混淆配置

Android编译优化

背景

为了使用java8及后续java新版本的特性,Google增加了一步编译过程—脱糖(desugaring),但这一步会导致更长的编译时间,这也是为什么Google会推出D8和R8编译器来优化编译速度。

什么是脱糖?

脱糖 即在编译阶段将在语法层面一些底层字节码不支持的特性转换为基础的字节码结构,(比如 List 上的泛型脱糖后在字节码层面实际为 Object); Android 工具链对 Java8 语法特性脱糖的过程可谓丰富多彩,当然他们的最终目的是一致的:使新的语法可以在所有的设备上运行。

D8

D8的功能是将Java字节码转化成dex代码,D8作为DX的一个替代方案。编译流程如下图所示:
D8

Android Studio 3.1版本开始,将D8作为默认的Dex编译器。如果想关闭D8,可以在gradle.properties里添加如下配置:

android.enableD8=false
android.enableD8.desugaring=false

开启D8的好处

  • 编译更快、时间更短
  • DEX编译时占用内容更小
  • .dex文件更小
  • D8编译的.dex文件拥有相同或者更好的运行性能

如果你的工程已经使用Java 8尽可能开启D8编译,不然可能会出现编译错误。

R8

R8作为原本Proguard 压缩与优化(minification、shrinking、optimization)部分的替代品,依然使用与Proguard一样的keep规则,是新一代的代码压缩工具。 R8之前采用D8+Proguard的形式构建,R8则将混淆和D8工具进行整合,目的是加速构建时间和减少输出apk的大小。

R8

Gradle插件版本达到3.4.0及以上,默认会开始R8进行代码优化。如果你不想开启R8,可以在gradle.properties里添加如下配置:

android.enableR8=false

开启R8的好处

  • 代码缩减:规避64引用限制
  • 资源缩减:移除不使用的资源
  • 混淆代码:减小DEX文件大小
  • 优化代码:进一步减小DEX文件大小

参考:

https://developer.android.google.cn/studio/build/shrink-code

相关评测报告
D8R8评测报告

AS多模块混淆配置

AS多模块下,我们可以采用各个模块单独配置方式,即proguard文件配置在各个模块下,在各自的build.gradle文件中引入; 也可以采用下方集中配置方式,将各模块的proguard文件集中配置到一个文件夹下,然后在app模块中集中引入所依赖的模块的proguard文件。
下面以cmcc_service这个app模块为例加以说明,

buildTypes {
        release {
            minifyEnabled true //开启混淆
            shrinkResources true //无用资源去除
            zipAlignEnabled true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'),'proguard-rules.pro',
                    '../proguardDefine/common-rules.pro', '../proguardDefine/live_lib-rules.pro',
                    '../proguardDefine/gs_api_adapter-rules.pro', '../proguardDefine/cmcc_service.pro',
                    '../proguardDefine/lib_voiceassistant-rules.pro','../proguardDefine/cmcc_softprobe-rules.pro'
            if (propertyHaveSigningConfigs)
                signingConfig signingConfigs.release
        }
}

其中,proguard-android-optimize.txt是android默认的一些通用混淆规则,proguard-rules.pro是app代码的混淆规则,proguardDefine文件夹下所依赖模块统一放置proguard规则的地方。

注意:引入的三方libs,一般都配有响应的proguard文件,所以不需要再重复配置,gradle编译时会将相关文件
proguard文件合并到一个configuration.txt文件中
configuration位置

proguard-android-optimize.txt

# 禁用一些代码简化和优化,以及字段和类合并
-optimizations !code/simplification/arithmetic,!code/simplification/cast,!field/*,!class/merging/*
# 运行优化 passes 的数量为 5,数值越高,混淆效果越好,但耗时也更长
-optimizationpasses 5
# 允许访问和修改保护代码
-allowaccessmodification

# 不允许使用大小写混合的类名
-dontusemixedcaseclassnames
# 不跳过非公共库类
-dontskipnonpubliclibraryclasses
# 详细输出
-verbose

# 保留一些反射所需的属性
-keepattributes *Annotation*,Signature,InnerClasses,EnclosingMethod
# 保留以下三个类及其公共成员
-keep public class com.google.vending.licensing.ILicensingService
-keep public class com.android.vending.licensing.ILicensingService
-keep public class com.google.android.vending.licensing.ILicensingService
# 忽略以下类,不输出 note 信息
-dontnote com.android.vending.licensing.ILicensingService
-dontnote com.google.vending.licensing.ILicensingService
-dontnote com.google.android.vending.licensing.ILicensingService

# 对于本地方法,参见 http://proguard.sourceforge.net/manual/examples.html#native
# 保留包含 native 方法的类和方法
-keepclasseswithmembernames,includedescriptorclasses class * {
    native <methods>;
}
# 保留公共的 View 子类的 set 和 get 方法
# 以便于使用属性动画
-keepclassmembers public class * extends android.view.View {
    void set*(***);
    *** get*();
}
# 保留 Activity 中可用于 XML 属性 onClick 中的方法
-keepclassmembers class * extends android.app.Activity {
    public void *(android.view.View);
}
# 对于枚举类,参见 http://proguard.sourceforge.net/manual/examples.html#enumerations
# 保留枚举类成员
-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}
# 保留实现 Parcelable 接口的类的 CREATOR 静态成员
-keepclassmembers class * implements android.os.Parcelable {
    public static final ** CREATOR;
}
# 保留 JavaScript 接口方法上的注解
-keepclassmembers class * {
    @android.webkit.JavascriptInterface <methods>;
}
# 支持库包含对新平台版本的引用
# 在应用链接旧版平台版本时,不要发出警告,因为它们是安全的
-dontnote android.support.**
-dontnote androidx.**
-dontwarn android.support.**
-dontwarn androidx.**
# 该类已弃用,但仍然保留用于向后兼容
-dontwarn android.util.FloatMath
#这段混淆规则用于保护使用了@Keep注解的类和成员不被混淆,以及忽略特定的冗余类。
-keep class android.support.annotation.Keep
-keep class androidx.annotation.Keep
#保留使用了@Keep注解的类和接口的所有成员
-keep @android.support.annotation.Keep class * {;}
-keep @androidx.annotation.Keep class * {;}
#保留使用了@Keep注解的类的方法
-keepclasseswithmembers class * {
@android.support.annotation.Keep <methods>;
}
-keepclasseswithmembers class * {
@androidx.annotation.Keep <methods>;
}
#保留使用了@Keep注解的类的字段
-keepclasseswithmembers class * {
@android.support.annotation.Keep <fields>;
}
-keepclasseswithmembers class * {
@androidx.annotation.Keep <fields>;
}
#保留使用了@Keep注解的类的构造方法
-keepclasseswithmembers class * {
@android.support.annotation.Keep <init>(...);
}
-keepclasseswithmembers class * {
@androidx.annotation.Keep <init>(...);
}
#忽略特定的冗余类
#android.jar和org.apache.http.legacy.jar中的类重复
-dontnote org.apache.http.**
-dontnote android.net.http.**
#android.jar和core-lambda-stubs.jar中的类重复
-dontnote java.lang.invoke.**

一些三方自带混淆规则

这些规则同样合并到了configuration.txt文件中
retrofit2混淆规则

# The proguard configuration file for the following section is /home/cl/.gradle/caches/transforms-3/29b6aa006718d6829551a18646bf70bb/transformed/rules/lib/META-INF/proguard/retrofit2.pro
# Retrofit does reflection on generic parameters. InnerClasses is required to use Signature and
# EnclosingMethod is required to use InnerClasses.
-keepattributes Signature, InnerClasses, EnclosingMethod

# Retain service method parameters when optimizing.
-keepclassmembers,allowshrinking,allowobfuscation interface * {
    @retrofit2.http.* <methods>;
}

# Ignore annotation used for build tooling.
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement

# Ignore JSR 305 annotations for embedding nullability information.
-dontwarn javax.annotation.**

# Guarded by a NoClassDefFoundError try/catch and only used when on the classpath.
-dontwarn kotlin.Unit

# Top-level functions that can only be used by Kotlin.
-dontwarn retrofit2.-KotlinExtensions

# End of content from /home/cl/.gradle/caches/transforms-3/29b6aa006718d6829551a18646bf70bb/transformed/rules/lib/META-INF/proguard/retrofit2.pro

RxJava2\RxAndroid混淆规则

-dontwarn java.util.concurrent.Flow*

Okhttp3混淆规则

# The proguard configuration file for the following section is /home/cl/.gradle/caches/transforms-3/af3ecb4c3ae4accf6423845d738f047d/transformed/rules/lib/META-INF/proguard/okhttp3.pro
# JSR 305 annotations are for embedding nullability information.
-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

# Animal Sniffer compileOnly dependency to ensure APIs are compatible with older versions of Java.
-dontwarn org.codehaus.mojo.animal_sniffer.*

# OkHttp platform used only on JVM and when Conscrypt dependency is available.
-dontwarn okhttp3.internal.platform.ConscryptPlatform

# End of content from /home/cl/.gradle/caches/transforms-3/af3ecb4c3ae4accf6423845d738f047d/transformed/rules/lib/META-INF/proguard/okhttp3.pro

更多可能用到的混淆配置

# 指定不去忽略非公共库的类
-dontskipnonpubliclibraryclasses
# 指定不去忽略非公共库的成员
-dontskipnonpubliclibraryclassmembers
# 混淆时不做预校验
-dontpreverify
# 忽略警告
-ignorewarnings
# 保留代码行号,方便异常信息的追踪
-keepattributes SourceFile,LineNumberTable
# appcompat库不做混淆
-keep class androidx.appcompat.**
#保留 AndroidManifest.xml 文件:防止删除 AndroidManifest.xml 文件中定义的组件
-keep public class * extends android.app.Fragment
-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.preference.Preference
-keep public class * extends android.view.View

#保留序列化,例如 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();
}

#带有Context、View、AttributeSet类型参数的初始化方法
-keepclasseswithmembers class * {
    public <init>(android.content.Context);
}
-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembers class * {
    public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers class * extends android.app.Activity {
   public void *(android.view.View);
}

#保留资源R类
-keep class **.R$* {*;}

#避免回调函数 onXXEvent 混淆
-keepclassmembers class * {
    void *(**On*Event);
    void *(**On*Listener);
    void *(**on*Changed);
}

#业务实体不做混淆,避免gson解析错误
-dontwarn com.grandstream.convergentconference.entity.**
-keep class com.grandstream.convergentconference.entity.** { *;}

#Rxjava、RxAndroid,官方ReadMe文档中说明无需特殊配置
-dontwarn java.util.concurrent.Flow*
#okhttp3、okio、retrofit,jar包中已包含相关proguard规则,无需配置
#其他一些配置

Android.bp混淆配置

android_app {
    name: "MyApp",
    package_name: "com.example.myapp",
    srcs: ["java/**/*.java"],
    manifest: "AndroidManifest.xml",
    dex_preopt: {
        enabled: true,
    },
    apk_cert_permissions: [
        "android.permission.ACCESS_FINE_LOCATION",
        "android.permission.RECORD_AUDIO",
        "android.permission.READ_CONTACTS",
    ],
    certificates: ["platform"],
    resource_files: ["res/**/*"],
    enable_proguard: true,
    proguard_flags: ["proguard-android.txt"],
    dex_preopt_image_dir: "target/product/${TARGET_PRODUCT}/obj/dex_preopt_image",
}

其中,enable_proguard 设置为 true 表示启用代码和资源混淆,proguard_flags 指定了 Proguard 混淆规则文件,可以在文件中指定代码和资源混淆规则。
resource_files 指定了应用程序的资源文件,包括 AndroidManifest.xml 文件。

android.mk混淆配置

LOCAL_PROGUARD_ENABLED := obfuscation optimization

LOCAL_PROGUARD_FLAG_FILES := proguard.flags
ifeq (eng,$(TARGET_BUILD_VARIANT))
    LOCAL_PROGUARD_FLAG_FILES += proguard-test.flags
else
    LOCAL_PROGUARD_FLAG_FILES += proguard-release.flags
endif

LOCAL_PROGUARD_ENABLED 有以下几种配置:

  1. LOCAL_PROGUARD_ENABLED := disabled:禁用混淆。
  2. LOCAL_PROGUARD_ENABLED := obfuscate:只开启代码混淆,不进行优化。
  3. LOCAL_PROGUARD_ENABLED := optimize:只开启优化,不进行代码混淆。
  4. LOCAL_PROGUARD_ENABLED := obfuscate optimize:同时开启代码混淆和优化。

编译系统默认应该会加载一个android通用的混淆文件,LOCAL_PROGUARD_FLAG_FILES用于指定app特定的proguard文件。
如果我们不太会配置这些选项,可以去查看原生应用的混淆配置,这对你会有很大启发。

结论

总之,一些通用混淆规则Android已经帮我写好了,我们关心的可能就是我们自己开发的那部分代码的混淆规则,混淆工作做的好有很多好处:
代码更安全、包体积更小、运行速度更快,但是混淆也会带来意想不到的运行异常,希望你做好测试,希望你尽快用起来。

参考

https://blog.csdn.net/Mr_dsw/article/details/90141647
https://blog.csdn.net/wwj_748/article/details/115874571
Android 混淆,新引入的D8、R8改变了什么?
https://toutiao.io/posts/ijfhzkv/preview

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/510283.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C语言】扫雷游戏

这里写目录标题 前言1.初始化棋盘2.展示棋盘3.布置雷4.开始扫雷4.1判断输赢4.2扫雷时连续性展开4.3展示玩法 5.整体代码展示5.1 game.h头文件展示5.2 game.c源文件展示5.3 text.c源文件展示 所属专栏&#xff1a;C语言 博主首页&#xff1a;初阳785 代码托管&#xff1a;chuyan…

了解 XML结构(一)

文章目录 1 XML定义2 了解XML结构3 XML节点类型4 加载读取XML5 小结 1 XML定义 XML是一种可扩展标记语言&#xff08;Extensible Markup Language, XML&#xff09;,可以用来标记数据&#xff0c;定义数据类型&#xff0c;是一种允许用户对自己的标记语言进行定义的源语言。 …

数据治理是一个部门的工作还是全业务体系的工作?_光点科技

随着互联网时代的到来&#xff0c;数据已成为企业生产和经营的重要资源。但是&#xff0c;随着数据量的不断增加和数据形态的多样化&#xff0c;如何管理和利用数据也成为了企业面临的一个重要问题。在这个过程中&#xff0c;数据治理成为了一个备受关注的话题。 那么&#xff…

ChatGPT1论文解读《Improving Language Understanding by Generative Pre-Training》

论文总结 以下是我阅读完整篇论文做的个人总结&#xff0c;基本包含了chatGPT1设计的完整框架思路&#xff0c;可以仅看【论文总结】章节。 在GPT1实现的核心架构中&#xff0c;包含两个阶段。 第一阶段 在第一阶段基于一个包含7000本书籍内容的海量未标注文本数据集进行无…

IP-Guard能否支持通过审批后才能发送邮件?

支持,但目前暂时只支持带有附件的邮件通过申请审批或者自我备案放开策略控制发送出去。 使用方式: 1、申请审批:设置了禁止发送邮件的邮件控制策略后,在申请权限-发送邮件中,设置允许发送,设置相关审批流程,管理员审批完成后即可发送。 -申请权限-审批流程 2、自我备案:…

SSM框架学习-注解开发第三方bean管理

1. 复习xml配置文件管理第三方bean 在Spring中&#xff0c;可以使用依赖注入&#xff08;Dependency Injection&#xff09;来管理和使用第三方Bean。Spring提供了多种方式来进行依赖注入&#xff0c;比如构造函数注入、Setter方法注入、字段注入等。下面以Setter方法注入为例&…

pycharm 常用插件,常用插件推荐

1. Key Promoter X 如果让我给新手推荐一个 PyCharm 必装插件&#xff0c;那一定是 Key Promoter X 。 它就相当于一个快捷键管理大师&#xff0c;它时刻地在&#xff1a; 教导你&#xff0c;当下你的这个操作&#xff0c;应该使用哪个快捷操作来提高效率&#xff1f;提醒你…

Scala学习(二)

文章目录 1.Scala的运算符1.1 Scala中的equals和 2.流程控制2.1 if2.2 Scala中的三目运算符2.3 for循环 3.循环中断 1.Scala的运算符 1.1 Scala中的equals和 回顾Java中的运算符 equals和,equals比较的为值&#xff0c; 比较的为地址 String a1new String("hi");…

【数据结构】线性表——带头双向循环链表

文章目录 带头双向循环链表带头双向循环链表主体结构带头双向循环链表操作函数介绍带头双向循环链表操作函数实现带头双向循环链表的初始化函数&#xff1a;打印函数带头双向循环链表插入函数&#xff1a;指定结点后插入和查找函数头插尾插 带头双向循环链表删除函数指定结点删…

2022东南大学网安916专硕上岸经验帖

本文目录 第一部分简单介绍我的一些选择 第二部分寒假大三下学期小学期暑假及大四上学期考前准备及考试过程考后估分与真实分数复试准备与复试过程复试结果导师选择经验对自己考研情况的评价一些建议 第一部分 简单介绍 最近忙完了毕业设计论文和教师资格证面试&#xff0c;终…

pc端项目的h5页面运行在手机浏览器使用vconsole查看页面元素、控制台、请求等信息

文章目录 一、vconsole介绍1. 作用2. 优势 二、使用1、jq项目和js项目2、vue项目 三、使用介绍1. 使用成功&#xff0c;在页面右下角会出现如下图的vConsole2. 常用功能&#xff08;控制台、请求、元素、存储器&#xff09; 一、vconsole介绍 1. 作用 使用vconsole来查看h5页…

怎么自学python?为什么选择python

自然是因为Python简单易学且应用领域广 Python近段时间一直涨势迅猛&#xff0c;在各大编程排行榜中崭露头角&#xff0c;得益于它多功能性和简单易上手的特性&#xff0c;让它可以在很多不同的工作中发挥重大作用。 正因如此&#xff0c;目前几乎所有大中型互联网企业都在使…

python写完程序怎么运行

python有两种运行方式&#xff0c;一种是在python交互式命令行下运行; 另一种是使用文本编辑器直接在命令行上运行。 注&#xff1a;以上两种运行方式均由CPython解释器编译运行。 当然&#xff0c;也可以将python代码写入eclipse中&#xff0c;用JPython解释器运行&#xff0c…

ACM - 字符串 - 基础(KMP)

字符串 一、KMP1、模板题 HDU1711 Number Sequence2、求最大匹配数 Ⅰ&#xff1a; HDU 2087 剪花布条&#xff08;子串不重叠&#xff09;3、求最大匹配数 Ⅱ&#xff1a;AcWing 831. KMP字符串&#xff08;子串可重叠&#xff09;4、s2 是不是 s1 的翻转&#xff1a;Leetcode…

draw.io二次开发(3)从删删减减开始定制自己的drawio

经过克隆代码、配置IntelliJ/IDEA和Tomcat、以及本地部署&#xff08;详见前几篇&#xff09;之后&#xff0c;终于到了上手改代码的环节了。 首先需要强调的一点是&#xff1a;千万不要去改 *.min.js 文件中的代码&#xff0c;这些文件都是生成的压缩代码&#xff0c;我们一定…

MySQL原理(四):事务

前言 上一篇介绍了 MySQL 的索引&#xff0c;这一篇将介绍事务相关的内容。 在 MySQL 的使用场景中&#xff0c;经常会有一个操作包含多个 SQL 语句&#xff0c;比如转账这个操作&#xff0c;至少包含从甲的账户中扣除金额和给乙的账户中增加金额这两个更新语句。那假如 MySQ…

如何优化VPS服务器性能,提升网站访问速度?

随着互联网的发展&#xff0c;越来越多的企业开始使用VPS服务器来托管其网站。然而&#xff0c;一些企业经常会遇到网站速度慢、响应时间长等问题&#xff0c;这不仅会影响用户的体验&#xff0c;还会导致客户流失。因此&#xff0c;优化VPS服务器的性能&#xff0c;提升网站访…

好程序员:Java培训班包就业靠谱吗?Java培训机构怎么选?

好程序员本身就是培训机构&#xff0c;现在已经10年多了。说句实在话&#xff0c;包就业的机构几乎没有&#xff0c;凡是给你说包就业的机构大多都不靠谱。你还得看机构的培训能力和就业率&#xff0c;其实能否找到工作还得看你自己在培训班学的怎么样了对吧&#xff0c;找工作…

CIAA 网络安全模型 — TLS v1.3 和 HTTPS 协议

目录 文章目录 目录SSL/TLSTLS 1.21. client_hello2. server_hello server_certificate sever_hello_done3. Certificate authentication4. client_key_exchange change_cipher_spec encrypted_handshake_message5. change_cipher_spec encrypted_handshake_message TLS 1…

portraiture3.5.6免费版PS图片磨皮软件

Portraiture是专注于图像后期处理软件研发的 Imagenomic, LLC重头产品之一&#xff0c;在摄影爱好者中极负盛名。Portraiture 可以将繁琐复杂的人像磨皮操作极致简化&#xff0c;不论是普通爱好者或专业后期处理人员&#xff0c;均能一键完成&#xff0c;被称为人像磨皮神器。 …