目前的 R8 是由早期的 D8 融合了一系列的包体 / 性能优化的操作而来,dx 负责将 jar 包整合压缩成 DEX 文件,它相对于后来新增的编译优化操作来说出现问题的概率更低,因此我们优先关注 R8 中涉及对字节码进行编辑的优化功能在线课堂。
由于 R8 在输入了 jar 包之后一直在内存中进行操作,并无中间产物,因此我们需要在相关功能的开始结束点手动将内存中所有由自定义 weaver plugin 生成的 class(有统一的后缀名)写到文件并保存在线课堂。
在多次打包复现问题之后,对阶段产物进行分析并未发现异常方法的字节码有任何变动,直到 dx 这一步,我们发现 if 语句在 class 字节码中跳转到指定标签的行为,在 dex 文件的 smali 字节码中被编译成了跳转到指定的函数偏移量在线课堂。
而之前 class 字节码中 if 语句指向的 label 找不到声明的问题,在 smali 中表现为直接将函数偏移量设为默认值 0X00,正好是函数体的第一行,和一开始反编译 apk 得到的结果吻合,这也就解释了为什么 if 语句最终会变成一个 do-while 语句在线课堂。