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

相关推荐
00后程序员张4 小时前
iOS 26 帧率测试实战指南,Liquid Glass 动画性能、滚动滑动帧率对比、旧机型流畅性与 uni-app 优化策略
android·ios·小程序·uni-app·cocoa·iphone·webview
新青年.5 小时前
【Android】解决安卓在隐藏系统栏后usb鼠标被隐藏的问题
android
游戏开发爱好者85 小时前
iPhone HTTPS 抓包实战,原理、常见工具、SSL Pinning 问题与替代工具的解决方案
android·ios·小程序·https·uni-app·iphone·ssl
2501_929382657 小时前
Will、NGC游戏模拟器 Dolphin海豚模拟器2509最新版 电脑+安卓版 附游戏
android·游戏·电脑
如此风景7 小时前
CompositionLocal 详解
android
如此风景7 小时前
staticCompositionLocalOf或compositionLocalOf介绍
android
沐怡旸7 小时前
【Android】【底层机制】为什么Android要使用Binder而不是传统的Socket?
android
lph0097 小时前
Android compose Room Sqlite 应用 (注入式)
android·数据库·sqlite
science138637 小时前
开播多进程演进(内存优化500+MB)
android