Description
异常类型:编译异常
tinker版本:如:1.9.9
gradle版本:如:3.3.2
是否使用热更新SDK:无
系统:Mac
在min sdk >= 21 时,Android Gradle Plugin,会忽视一切指定分包规则的参数,比如multiDexKeepProguard。
Google应该是考虑到:sdk 21开始android原生支持多dex,指定分包规则没有必要,并影响编译速度,所以在代码中显式的对min sdk >= 21的时候屏蔽了分包规则。
目前Tinker仍然要求loader相关类必须在第一个dex中,请问:
Tinker在min sdk >=21的时候是否有必要强行要求loader相关类在第一个dex?
如果没有必要的话,Tinker的Gradle Plugin需要移除相关检查和报错,否则就只能设置ignoreWarnings = true
才能编译通过。
如果有必要的话,需要寻找方案解决Android Gradle Plugin忽视分包规则的问题。
另外,在其他issue里面,很多loader classes are found in old secondary dex
相关问题是由这个引起的。其中很多都没有引起重视,被直接closed+wontfix了。
在这些issue里,@NickKJ 提到的通过CLI可以解决,是因为:
他本人项目min sdk < 21,而通过点击Android Studio的按钮执行时,Studio会注入init.gradle,对build type为debug的variant覆写min sdk为很高的版本,从而提高编译速度以及启用更高级的profile功能。所以表现为通过cli执行可以解决。实际上如果项目本来的min sdk >=21, 通过cli也无法解决这个问题。
Activity
tys282000 commentedon May 5, 2019
多谢反馈。Tinker的机制决定了在dalvik机器上loader类目前还是必须出现在主dex里,对于minSDK大于等于21的应用只会跑在ART上,理论上暂时可以靠ignoreWarning规避,但是仅限规避这个warning,因此开启这个开关之后要记得留意编译输出的警告信息了。
其实这个坑我最近看AGP源码也发现了,上周有位开发者也反馈了类似的问题,一开始我怀疑是配置问题,后来确认所有配置都正确之后开始怀疑是不是AGP新引入的native multidex忽略了所有关于分包的配置。接着我试了各种hack方法都没法解决,最后得出的结论是只能自己接管AGP的multidex逻辑自行处理分包,或者通过additionalParams的方式给dx或者d8追加maindexlist参数的方式来解决。
虽然Loader类随便分在minSDK大于等于21的机器上应该不会有啥问题,但考虑到新旧apk分包结果的变化会使补丁大小显著增大,因此我还是计划先留着这个检查。后面的版本会考虑根据用户传入的规则文件生成maindexlist传给dx或者d8的方案来规避这个问题。
noproxy commentedon May 6, 2019
可以先加一个单独屏蔽这个warning的开关,避免其他问题被忽略
tys282000 commentedon May 6, 2019
嗯嗯,对滴。近期我抽时间加一下吧。
tys282000 commentedon May 7, 2019
其实minSDK>=21的时候直接ignoreWarning还是不行,因为loader类里有个校验注入的dex是否生效的TinkerTestDexLoad类,如果被分到了其他dex,在合成新的补丁dex之后会导致合成的产物里这个类出现两次,其中Tinker生成的test.dex里的那个会被另外一个覆盖,导致补丁加载失败。
所以至少要保证
com.tencent.tinker.loader.TinkerTestDexLoad
这个类出现在主dex才行。fixes Tencent#1084
muxi166 commentedon May 15, 2019
什么时候修复发版呢
Merge pull request #1096 from noproxy/dev
awxy commentedon May 22, 2019
在1.9.13的版本修复了?很急
awxy commentedon May 23, 2019
additionalParams添加无效
18 remaining items