Closed wzjing closed 4 years ago
兄弟,你去错地方了....
@youxiachai 不太懂,啥意思?这个地方的代码不能提issue吗?TinkerProguardConfigTask.groovy
@wzjing tinker 和tinker-patch 不是一个项目啊....
我指的是这个项目里自带的插件,不是tinkerpatch那个付费平台的插件@youxiachai
@wzjing
3个月前遇到了.实际上应该是tinker里面这个类的keep存在问题.
public final class TinkerApplicationInlineFence extends Handler {
private final ApplicationLike mAppLike;
tinker的gradle插件会插入如下keep规则
-keep class com.tencent.tinker.entry.TinkerApplicationInlineFence {
*;
}
这条规则会导致真正的ApplicationLike实现类(多数情况下就是我们实际app的Application类),引用的所有类都被放到maindex... 改成-keep class com.tencent.tinker.entry.TinkerApplicationInlineFence可以让maindex中减少很多.
附上我们在build.gradle中的解决代码.
android.applicationVariants.all { variant ->
// 删除Tinker添加的DexKeepProguard规则,防止打包时出现mainDex methods>65535
// 在Tinker 1.9.14.5上测试通过,后续Tinker版本可能会修复此问题, 升级Tinker时注意维护
Task fixTinkerDexKeepProguard = task("fixTinkerDexKeepProguardFor${variant.name.capitalize()}")
fixTinkerDexKeepProguard.doLast{
def tinkerMultidexKeepTask = project.tasks.findByName("tinkerProcess${variant.name.capitalize()}MultidexKeep")
def multiDexKeepProguardFile = file(tinkerMultidexKeepTask.multiDexKeepProguard)
def lines = []
def skipNextLine = false
def processed = false
multiDexKeepProguardFile.text.eachLine {line->
if(skipNextLine){
skipNextLine = false
processed = true
}else if(line.contains("-keep class com.tencent.tinker.entry.TinkerApplicationInlineFence")){
//删除此条之后的*
lines.add(line)
skipNextLine = true
}else {
lines.add(line)
}
}
FileWriter fr = new FileWriter(multiDexKeepProguardFile,false)
try {
for (String line : lines) {
fr.write(line)
fr.write("\n")
}
} finally {
fr.close()
}
if(!processed){
project.logger.log(LogLevel.ERROR,"未能成功清除Tinker添加错误的MultidexKeep规则,可能出现65536问题")
}
}
}
@icemanstudy 是个不错的办法,但是直接删掉这条规则是否会有兼容问题呢?目前我是在ApplicationLike里反射调用实际的启动代码,达到切断依赖的目的(但启动时长增加了100ms,也不太能接受)
临时解决方案基本都有了:
是这条自动生成的multidex规则导致的:
-keep class com.tencent.tinker.loader.app.TinkerInlineFenceAction {
*;
}
class YourApplicationLike extends DefaultApplicationLike {
@Override
void onCreate() {
// 反射调用实际的启动代码,这样就不会被keep到multidexkeeplist里了
Class<MyDelegate> delegateClazz = Class.forName("com.example.MyDelegate");
MyDelegate delegate = delegate.getConstructor().newInstance();
Method onCreateMethod = delegateClazz.getDeclaredMethod("onCreate")
onCreateMethod.invoke(delegate)
}
}
希望Tinker官方能在后续版本给个官方解决方案吧🤘
插件自动生的multidex keep规则中包含这一条:
这个类里又直接调用了 ApplicationLike.onBaseContextAttached()和ApplicationLike.onCreate(),由于依赖规则的传递,导致所有在ApplicationLIke中添加的启动代码以及其依赖都被添加到了multidexKeepList中。正常情况下,不接入tinker,把这些启动代码直接放在Application的onCreate也只产生了800-900个keep的class,但是用这一条tinker的规则就导致keep的class骤增到了115000+个,众所周知,mainDex只能keep65535个class,请问,这条规则是否可以细化?ApplicationLike内的类是不是不用全部keep?