Android编译优化之混淆配置

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

网安笔记 09 PKI PMI

PKI PMI PKI 公钥基础设施 public key infrastructure 遵循标准的&#xff0c;利用公钥理论和技术建立的提供安全服务的基础设施 **目的&#xff1a;**身份认证&#xff0c;点滴信息不完整&#xff0c;不可抵赖&#xff0c;提供可靠安全服务 **任务&#xff1a;**可信任数字…

使用@Autowired、@Qualifier、@Primary注解自动装配组件

1.Autowired、Qualifier、Primary注解 1.1.Autowired注解 Autowired注解可以对类成员变量、方法和构造函数进行标注&#xff0c;完成自动装配的工作。 package org.springframework.beans.factory.annotation;import java.lang.annotation.Documented; import java.lang.ann…

数据结构学习记录——哈夫曼树(什么是哈夫曼树、哈夫曼树的定义、哈夫曼树的构造、哈夫曼树的特点、哈夫曼编码)

目录 什么是哈夫曼树 哈夫曼树的定义 哈夫曼树的构造 图解操作 代码实现 代码解析 哈夫曼树的特点 哈夫曼编码 不等长编码 二叉树用于编码 哈夫曼编码实例 什么是哈夫曼树 我们先举个例子&#xff1a; 要将百分制的考试成绩转化成五分制的成绩 if(score < …

固态继电器的优点

固态继电器的优点包括紧凑性、抗冲击性和长寿命。以下是这些 SSR 优势中最重要的优势&#xff0c;让您了解为什么这项技术最适合您的应用&#xff1a; 开关速度快 固态继电器器件的主要优点之一是其开关速度。由于无需移动机械部件&#xff0c;SSR 可以在几微秒内切换。这是对…

【Java笔试强训 35】

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔&#x1f93a;&#x1f93a;&#x1f93a; 目录 一、选择题 二、编程题 &#x1f525;年会抽奖…

小红书达人等级有哪些,达人种草力度判断

小红书对于产品及品牌的传播作用&#xff0c;来自于达人自身的分享。以笔记为媒介&#xff0c;对产品进行情景化展示&#xff0c;从而吸引消费&#xff0c;就被称作是种草。而种草力度的强弱&#xff0c;则与达人等级息息相关。下面&#xff0c;就来跟详细为大家解读。 一、小红…

设计模式——适配器模式(类适配器、对象适配器)

是什么&#xff1f; 我们平时的有线耳机接口分为USB的和Type-C的接口&#xff0c;但是手机的耳机插口却只有一个&#xff0c;像华为的耳机插口现在基本都是Type-c的&#xff0c;那如果我们现在只有USB接口的耳机怎么办呢&#xff0c;这个时候就需要使用到一个转换器&#xff0c…

公路交通气象站——提供及时的交通气象信息服务

我国幅员辽阔&#xff0c;跨经纬度广&#xff0c;气候多样。从气候类型划分&#xff1a;可以分为季风气候、温带大陆性气候和高寒气候。 气象的变化也在直接影响着我国各个地区的道路建设及通行&#xff0c;由于部分路段地势险峻伴随恶劣的气象变化&#xff0c;会直接影响驾驶人…

Java 10 字符串

1.API 1.1API 概述 什么是API ​ API (Application Programming Interface) &#xff1a;应用程序编程接口 java 中的 API ​ 指的就是 JDK 中提供的各种功能的 Java 类&#xff0c;这些类将底层的实现封装了起来&#xff0c;我们不需要关心这些类是如何实现的&#xff0c;只…

LeetCoed 2, 23, 25, 112, 113

文章目录 1. 两数相加2. K 个一组翻转链表3. 合并 K 个升序链表4. 路径总和I5. 路径总和II 1. 两数相加 题目详情见: LeetCode2. 两数相加 题目描述相对来说比较绕, 我们可以直接理解为两个多位的整数相加, 只不过整数的每一位都是通过链表进行存储; 比如, 整数 342, 通过链表…

三分钟教你Mac下安装VmWare虚拟机

大数据课程课前环境准备&#xff1a;mac中安装三台linux服务器 一、课前准备 准备一台内存最少8G&#xff08;建议16G&#xff09;、cpu i7 4核的电脑 二、课堂主题 安装虚拟化软件VMware准备3台linux虚拟机 三、课堂目标 完成mac下3个虚拟机的安装 四、知识要点 文档说…

浅析智慧充电桩云平台的技术设计方案

自从我国提出“新基建”以来&#xff0c;充电基础设施产业也成为行业的话题与关注焦点。据数据统计&#xff0c;2021年&#xff0c;中国新能源汽车保有量达到784万辆&#xff0c;预计2025年&#xff0c;中国新能源汽车保有量达到2672万辆&#xff0c;2025年充电桩数量将达到654…

【沐风老师】一步一步教你在3dMax中进行UVW贴图和展开UVW的方法

将简单或程序材质应用于对象并不难。但是当表面需要在其上显示某种纹理时&#xff0c;它会变得更加复杂。任何纹理贴图都放在材质的 Diffuse 插槽中&#xff0c;但渲染的结果可能无法预测。这就是为什么我们需要了解 3DMAX 如何将纹理应用于 3D 对象&#xff0c;什么是 UVW 贴图…

weblogic ssrf 漏洞复现

一.前言 Weblogic中存在一个SSRF漏洞&#xff0c;利用该漏洞可以发送任意HTTP请求&#xff0c;进而攻击内网中redis、fastcgi等脆弱组件。 二.环境搭建 在docker中开启环境 sudo docker-compose up -d sudo docker-compose ps #查看状态访问http://your-ip:7001/uddiexpl…

【数码】收音机,德生PL380使用教程与注意事项

文章目录 1、主界面功能介绍&#xff08;注意闹钟和自动关机&#xff09;2、电池和电池模式的匹配3、收音机天线与信号&#xff0c;耳机与噪音F、参考资料 1、主界面功能介绍&#xff08;注意闹钟和自动关机&#xff09; 红色的按钮&#xff1a;power 按一下开机&#xff0c;按…

25个著名的WordPress网站案例

想创建免费网站吗&#xff1f;从易服客建站平台开始 500M免费空间&#xff0c;可升级为20GB电子商务网站 创建免费网站 WordPress 内容管理系统为全球35%的网站提供支持。鉴于目前有 17 亿个站点&#xff0c;并且还在增加&#xff0c;您可以算出每秒向网站访问者提供内容的W…

牛客网剑指offer|中等题day2|JZ22链表中倒数最后k个结点(简单)、JZ35复杂链表的复制(复杂)、JZ77按之字形顺序打印二叉树(中等)

JZ22链表中倒数最后k个结点(简单) 链接&#xff1a;链表中倒数最后k个结点_牛客题霸_牛客网 /*** struct ListNode {* int val;* struct ListNode *next;* ListNode(int x) : val(x), next(nullptr) {}* };*/ class Solution { public:/*** 代码中的类名、方法名、参数名已经指…

一、PEMFC基础之热力学

一、PEMFC基础之热力学 1.内能U、焓H、熵S、吉布斯自由能G、赫姆霍兹自由能F关系图2.可逆电压与温度和压力的关系3.能斯特方程4.燃料电池效率 1.内能U、焓H、熵S、吉布斯自由能G、赫姆霍兹自由能F关系图 2.可逆电压与温度和压力的关系 标准状态可逆电压Er计算&#xff1a; E …

基于springboot的4S店车辆管理系统(源码等)

摘 要 随着信息技术和网络技术的飞速发展&#xff0c;人类已进入全新信息化时代&#xff0c;传统管理技术已无法高效&#xff0c;便捷地管理信息。为了迎合时代需求&#xff0c;优化管理效率&#xff0c;各种各样的管理系统应运而生&#xff0c;各行各业相继进入信息管理时代&…

Linux进程状态及优先级

本文已收录至《Linux知识与编程》专栏&#xff01; 作者&#xff1a;ARMCSKGT 演示环境&#xff1a;CentOS 7 进程状态及优先级 前言正文进程状态就绪运行状态R阻塞睡眠状态 S休眠状态D挂起 暂停状态T前台与后台进程待追踪暂停状态t 死亡状态 X僵尸状态 Z 孤儿进程进程优先级查…