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 优化的时候 把我这个类当做是抽象类处理,对于抽象类来说是无法享受此优化的

相关推荐
muyouking113 小时前
Tauri Android 开发踩坑实录:从 Gradle 版本冲突到离线构建成功
android·rust
Jerry4 小时前
Compose 为元素赋予动画特效
android
Jeled5 小时前
协程工具类
android·android studio
阿兰哥8 小时前
【调试篇5】TransactionTooLargeException 原理解析
android·性能优化·源码
爱吃水蜜桃的奥特曼9 小时前
玩Android Flutter版本,通过项目了解Flutter项目快速搭建开发
android·flutter
太过平凡的小蚂蚁9 小时前
Android 版本特性完全解析:从6.0到16.0的实用指南
android
杨筱毅9 小时前
【底层机制】【Android】深入理解UI体系与绘制机制
android·底层机制
介一安全10 小时前
【Frida Android】基础篇8:Java层Hook基础——调用带对象参数的方法
android·网络安全·逆向·安全性测试·frida
puyaCheer10 小时前
Android 13 启动的时候会显示一下logo,很不友好
android·gitee
long_hai_d11 小时前
Aosp14桌面壁纸和锁屏壁纸的设置和加载分析
android