R8 如何优化我们的代码(3) -- 值假设与常量

assumevalues 用法

assumevalues 告知 r8 指定的字段值或者方法值将始终处于特定范围内或等于某个单一值

先看一段简单的代码

kotlin 复制代码
class Count {
    public static void main(String... args) {
        count = 3;
        sayHi();
    }

    private static int count = 1;

    private static void sayHi() {
        if (count < 0) {
            throw new IllegalStateException();
        }
        for (int i = 0; i < count; i++) {
            System.out.println("Hi!");
        }
    }
}

混淆前

混淆后, 不但做了内联,还帮我们做了一定程度上的剪枝处理

再看下我们常用的 android 版本判断

kotlin 复制代码
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        if (Build.VERSION.SDK_INT >= 32) {
            println("32+++")
        } else if (Build.VERSION.SDK_INT >= 31) {
            println("31")
        } else {
            println("<31")
        }

    }
}

假设我们的 min sdk 是 31,

混淆代码以后,代码没有发生什么变化

但是在 proguard 文件中 加入一段代码,因为我们明确知道 我们最小 min sdk 是 31 的

kotlin 复制代码
-assumevalues class android.os.Build$VERSION {
  int SDK_INT return 31..2147483647;
}

再看 r8 混淆后的效果, 嗯这次就符合预期了

注意我们 androidx 里面有大量的 android 版本判断,最低是到 14,所以如果我们可以根据我们项目实际的效果配置这个对应的assumevalues,可以节约不少代码,提高程序执行效率

agp>7.0的版本中我实测是不需要自己手动写Build$VERSION 的assumevalues了,agp 和 r8 会自动配合处理好,这里只是演示一下这个 proguard 写法的作用。

对于部分经常做sdk 的同学来说,在你的 sdk 接入文档中 ,写好对应的assumevalues 也是有助于你 sdk 的性能的,大部分做 app 的知道有这么个东西即可

字符串常量 与类常量

字符串常量的优化 相对而言就不那么重要了,主要是这部分的优化一般情况下 不会引发什么错误,至少我目前还没碰到过 因为字符串常量优化 而导致的运行时 crash 或者 build 失败,大家知道有这么个东西即可

kotlin 复制代码
static String patternHost(String pattern) {
  return pattern.startsWith(WILDCARD)
      ? pattern.substring(WILDCARD.length())
      : pattern;
}

例如上面这段代码,WILDCARD.length() 在 r8 处理之后 会变成一个常量值,避免 程序运行时再去常量池里去找 这里就不具体演示优化前和优化后的字节码了,大家自行体会即可

不过这里大家可能会疑惑,如果不是 activity,是个普通类,还能这样写吗? 按照jw 的原文

的表述,普通类也可以享受此优化,因为 混淆和优化 都是 r8来控制,r8 完全可以做到 先混淆,再优化 这样就可以保证 getSimpleName 方法拿到的值是混淆后的类名。

我这里实验起来的方案来看,当前 r8 版本应该没有做类似的优化了

这里有知道原因的大佬可以评论区里说下原因。

个人猜测,可能是我用于测试的类写的过于简单 导致r8 优化的时候 把我这个类当做是抽象类处理,对于抽象类来说是无法享受此优化的

相关推荐
峥嵘life1 小时前
Android16 311Y3 EAP-TLS 网络连接失败分析与修复总结
android·开发语言·人工智能·php
Kapaseker2 小时前
破坏性更新 - 解读 Jetpack Compose 1.12
android·kotlin
雨白3 小时前
我的 UML 学习笔记:结合 Android 实例看懂 4 种常用图表
android·架构
怣疯knight3 小时前
快速判断apk有没有支持16kb页面标准
android
风流 少年4 小时前
Spring AI 2.0:Advisor
android·人工智能·spring
YM52e5 小时前
分页查询的基石:ArkTS 为鸿蒙商品列表设计 LIMIT/OFFSET 的表
android·学习·华为·harmonyos
安卓与AI研习社7 小时前
Android ANR 到底怎么定位?从触发原理到日志判断的完整方法
android
阿pin9 小时前
Android随笔-MVI
android·mvi
leobertlan9 小时前
【好玩系列】训练一个神经网络指导小孩玩游戏
android·机器学习·程序员
Android-Flutter10 小时前
android LeakCanary 工作原理 详解
android·kotlin