快速应用「幽灵调用」的正式修复

今天傍晚,Google将幽灵调用的修复正式合入到R8的诸多版本中,App终于可以用起来了。下面我简单介绍下,再讲下如何在App中快速应用。

整体情况

Google已将修复合入到以下几个R8版本中,注意,是R8版本,而非AGP(Android Gradle Plugin)版本:

  • 8.10.36
  • 8.11.28
  • 8.12.24
  • 8.13.10
  • 9.0.11-dev

对于R8 8.x系列,它们通常会随着 AGP的迭代进入正式版本。举个例子:AGP 目前最新版本是 8.13,未来如果继续发 8.13.1、8.13.2 等小版本,就有可能包含这次 R8 的修复。但也不排除某个大版本只发一次,如果没有新迭代,那这个 AGP 分支就不会带上修复。

而对于即将在下半年发布的 AGP 9.0,Google明确提到会包含此次修复。

当下的解决方案

未来版本什么时候发布我们无法完全确定,那现在该怎么办?

答案是:通过替换 R8 的方式来立即应用修复 。Google 官方提供了操作方法:r8.googlesource.com/r8/#replaci...

To override the embedded version with a prebuilt R8 with version , merge the following into the top level settings.gradle or settings.gradle.kts:

scss 复制代码
pluginManagement {
    buildscript {
        repositories {
            mavenCentral()
            maven {
                url = uri("https://storage.googleapis.com/r8-releases/raw")
            }
        }
        dependencies {
            classpath("com.android.tools:r8:<version>")
        }
    }
}

核心思路很简单:

  • Google 已经把这些修复过的 R8 版本存档在仓库:storage.googleapis.com/r8-releases...
  • 我们只需要在构建脚本里指定这个仓库,并在 classpath 中写入需要的 R8 版本号,就能让 AGP 使用我们指定的 R8,自然也就包含了修复。

实测验证

我在本地项目里亲测了一遍,配置如下:

arduino 复制代码
classpath "com.android.tools:r8:8.10.36"

然后打开 minifyEnabled,编译生成 release APK,并对其中的 classes.dex 执行:

复制代码
dexdump -d classes.dex

结果显示:

sql 复制代码
09a198:                    |[09a198] com.xxx.testdedupe.MyViewA.onDetachedFromWindow:()V
09a1a8: 6f10 540b 0100     |0000: invoke-super {v1}, Landroid/view/View;.onDetachedFromWindow:()V // method@0b54
09a1ae: 6300 0000          |0003: sget-boolean v0, LA/c;.a:Z // field@0000
09a1b2: 3800 0900          |0005: if-eqz v0, 000e // +0009
09a1b6: 6e10 c80a 0100     |0007: invoke-virtual {v1}, Landroid/view/View;.getAlpha:()F // method@0ac8
09a1bc: 0a00               |000a: move-result v0
09a1be: 6e20 900b 0100     |000b: invoke-virtual {v1, v0}, Landroid/view/View;.setAlpha:(F)V // method@0b90
09a1c4: 0e00               |000e: return-void
sql 复制代码
09a1fc:                    |[09a1fc] com.xxx.testdedupe.MyViewB.onDetachedFromWindow:()V
09a20c: 6f10 540b 0100     |0000: invoke-super {v1}, Landroid/view/View;.onDetachedFromWindow:()V // method@0b54
09a212: 6300 0000          |0003: sget-boolean v0, LA/c;.a:Z // field@0000
09a216: 3800 0900          |0005: if-eqz v0, 000e // +0009
09a21a: 6e10 c80a 0100     |0007: invoke-virtual {v1}, Landroid/view/View;.getAlpha:()F // method@0ac8
09a220: 0a00               |000a: move-result v0
09a222: 6e20 900b 0100     |000b: invoke-virtual {v1, v0}, Landroid/view/View;.setAlpha:(F)V // method@0b90
09a228: 0e00               |000e: return-void

虽然字节码内容完全一样,但因为有invoke-super指令,所以无法复用,字节码地址不同表明了这一点。

这就说明修复生效,幽灵调用的问题彻底解决。

相关推荐
方白羽2 分钟前
Android多层嵌套RecyclerView滚动
android·java·kotlin
菜就多学1 小时前
SurfaceControlViewHost 实现跨进程UI渲染
android·设计
2501_915106321 小时前
iOS App 测试工具全景分析,构建从开发调试到线上监控的多阶段工具链体系
android·测试工具·ios·小程序·uni-app·iphone·webview
小羊在奋斗2 小时前
MySQL表的约束:从基础到核心(附场景+案例)
android·数据库·mysql
e***19353 小时前
MySQL-mysql zip安装包配置教程
android·mysql·adb
方白羽3 小时前
Kotlin遇上Java 静态方法
android·java·kotlin
q***06474 小时前
SpringSecurity相关jar包的介绍
android·前端·后端
7***31885 小时前
若依微服务中配置 MySQL + DM 多数据源
android·mysql·微服务
我是好小孩5 小时前
【Android】常见的架构模式:MVC, MCP, MVVM
android·架构·mvc
Digitally5 小时前
如何通过蓝牙将联系人从 iPhone 传输到 Android
android·ios·iphone