Skip to content

multiDexKeepProguard won't work if minSDK >= 21 #1084

Closed
@noproxy

Description

@noproxy
Contributor

异常类型:编译异常
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了。

如:
#859
#877
#938
#993
#1032

在这些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

tys282000 commented on May 5, 2019

@tys282000
Collaborator

多谢反馈。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

noproxy commented on May 6, 2019

@noproxy
ContributorAuthor

可以先加一个单独屏蔽这个warning的开关,避免其他问题被忽略

tys282000

tys282000 commented on May 6, 2019

@tys282000
Collaborator

嗯嗯,对滴。近期我抽时间加一下吧。

tys282000

tys282000 commented on May 7, 2019

@tys282000
Collaborator

其实minSDK>=21的时候直接ignoreWarning还是不行,因为loader类里有个校验注入的dex是否生效的TinkerTestDexLoad类,如果被分到了其他dex,在合成新的补丁dex之后会导致合成的产物里这个类出现两次,其中Tinker生成的test.dex里的那个会被另外一个覆盖,导致补丁加载失败。

所以至少要保证com.tencent.tinker.loader.TinkerTestDexLoad这个类出现在主dex才行。

added a commit that references this issue on May 14, 2019
8be7181
muxi166

muxi166 commented on May 15, 2019

@muxi166

什么时候修复发版呢

added a commit that references this issue on May 15, 2019

Merge pull request #1096 from noproxy/dev

b4ab960
awxy

awxy commented on May 22, 2019

@awxy

其实minSDK>=21的时候直接ignoreWarning还是不行,因为loader类里有个校验注入的dex是否生效的TinkerTestDexLoad类,如果被分到了其他dex,在合成新的补丁dex之后会导致合成的产物里这个类出现两次,其中Tinker生成的test.dex里的那个会被另外一个覆盖,导致补丁加载失败。

所以至少要保证com.tencent.tinker.loader.TinkerTestDexLoad这个类出现在主dex才行。

在1.9.13的版本修复了?很急

awxy

awxy commented on May 23, 2019

@awxy

其实minSDK>=21的时候直接ignoreWarning还是不行,因为loader类里有个校验注入的dex是否生效的TinkerTestDexLoad类,如果被分到了其他dex,在合成新的补丁dex之后会导致合成的产物里这个类出现两次,其中Tinker生成的test.dex里的那个会被另外一个覆盖,导致补丁加载失败。

所以至少要保证com.tencent.tinker.loader.TinkerTestDexLoad这个类出现在主dex才行。

additionalParams添加无效

18 remaining items

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @feicien@muxi166@dotcink@consonluo@noproxy

        Issue actions

          multiDexKeepProguard won't work if minSDK >= 21 · Issue #1084 · Tencent/tinker