tinker
tinker copied to clipboard
R8 outlining 与 Tinker 存在兼容性问题
异常类型:app运行时异常
手机型号:无关
手机系统版本:无关
tinker版本:1.9.13.1
gradle版本:5.1.1
是否使用热更新SDK: 否
系统:如:Mac
堆栈/日志:
java.lang.NoSuchMethodError: No static method Qc(Ljava/lang/String;)Ljava/lang/StringBuilder; in class Le/c/a/a/a; or its super classes (declaration of 'e.c.a.a.a' appears in /data/app/***-1/base.apk)
at f.a.y.n.
关于R8 outlining https://jakewharton.com/r8-optimization-method-outlining/
R8 outlining 会将频繁出现的代码外联到com.android.tools.r8.GeneratedOutlineSupport类中进行复用。 在上面的stacktrace当中,GeneratedOutlineSupport被重命名为e.c.a.a.a。 在这种优化之后,Tinker loader和App的业务代码就会共同使用这个外联类,这就破坏了Tinker loader和App业务代码的隔离。 安装补丁之后,由于Tinker loader代码使用了外联类,基础Apk中的外联类被加载进内存。而后,热修复过后的业务代码同样使用了这个类里的函数,但由于这个类已经被加载到内存中,热修复过后的业务代码会引用热修复之前的外联类。若外联类在热修复前后是不一样的,就会带来崩溃。
@tomystang
这个问题有进展吗
@paul1992li 我们目前会在编译结束之后,用apktool反编译apk,将smali里tinker的部分全部替换成我们预先编译好的smali,然后再编译回去。
我司也遇到了这个问题
在proguard规则中,增加-dontoptimize选项可以,关闭所有代码优化可以解决这个问题,包大小会略有增加
这个问题除了楼上的同学关闭优化的解决方法之外,还有没有其他解决的途径?
经过测试发现一种不关闭优化的解决方法,把tinker.loader包下的所有打差异包不过的方法,都采用try{}catch(){}的方法修改一下,然后再打差异包,这样就不会报这样的错误了,缺点就是,不能使用gradle依赖了,只能把代码下载到本地然后使用修改loader包下的源码,最后把loader包打成aar的方法,这里可以直接运行gradlew buildTinkerSdk这行命令就可以在build文件夹下获取到aar,最后把aar依赖到自己项目中,亲测有效,目前没发现其他更好的方法,如若有烦请告知!