tinker icon indicating copy to clipboard operation
tinker copied to clipboard

R8 outlining 与 Tinker 存在兼容性问题

Open hqzxzwb opened this issue 4 years ago • 8 comments

异常类型: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.(HttpHeaderUtil.java:20) at ***.OkHttpClientTransformer.b(OkHttpClientTransformer.java:3) at f.a.c.b.intercept(lambda) at k.a.c.g.a(RealInterceptorChain.java:11) at k.a.c.g.e(RealInterceptorChain.java:1) at ***.OkHttpClientTransformer.a(OkHttpClientTransformer.java:3) at f.a.c.a.intercept(lambda) at k.a.c.g.a(RealInterceptorChain.java:11) at k.a.c.g.e(RealInterceptorChain.java:1) at k.K.Hka(RealCall.java:23) at k.K.execute(RealCall.java:14) at f.a.s.g.e._b(HotFixBoot.kt:14) at ***.HotFixService.N(HotFixService.kt:1) at ***.HotFixService.onHandleIntent(HotFixService.kt:1) at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:68) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:154) at android.os.HandlerThread.run(HandlerThread.java:61)

hqzxzwb avatar Jul 08 '19 09:07 hqzxzwb

关于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中的外联类被加载进内存。而后,热修复过后的业务代码同样使用了这个类里的函数,但由于这个类已经被加载到内存中,热修复过后的业务代码会引用热修复之前的外联类。若外联类在热修复前后是不一样的,就会带来崩溃。

hqzxzwb avatar Jul 08 '19 09:07 hqzxzwb

@tomystang

hqzxzwb avatar Jul 08 '19 09:07 hqzxzwb

这个问题有进展吗

paul1992li avatar Jul 30 '19 10:07 paul1992li

@paul1992li 我们目前会在编译结束之后,用apktool反编译apk,将smali里tinker的部分全部替换成我们预先编译好的smali,然后再编译回去。

hqzxzwb avatar Dec 04 '19 09:12 hqzxzwb

我司也遇到了这个问题

JaydenHoFly avatar Jan 14 '20 08:01 JaydenHoFly

在proguard规则中,增加-dontoptimize选项可以,关闭所有代码优化可以解决这个问题,包大小会略有增加

Ivan-ma avatar Jun 07 '21 03:06 Ivan-ma

这个问题除了楼上的同学关闭优化的解决方法之外,还有没有其他解决的途径?

wuxiaojun123 avatar Jan 10 '22 10:01 wuxiaojun123

经过测试发现一种不关闭优化的解决方法,把tinker.loader包下的所有打差异包不过的方法,都采用try{}catch(){}的方法修改一下,然后再打差异包,这样就不会报这样的错误了,缺点就是,不能使用gradle依赖了,只能把代码下载到本地然后使用修改loader包下的源码,最后把loader包打成aar的方法,这里可以直接运行gradlew buildTinkerSdk这行命令就可以在build文件夹下获取到aar,最后把aar依赖到自己项目中,亲测有效,目前没发现其他更好的方法,如若有烦请告知!

wuxiaojun123 avatar Jan 12 '22 06:01 wuxiaojun123