Open PhantomQi opened 2 years ago
triggerPMDexOptOnDemand内部采用了两种突破opt策略:performDexOptSecondary 和 registerDexModule。近期用下面的实验方法做了一次线上灰度实验,得到的结论是绝大部分厂商或机型上registerDexModule能获得更短的补丁加载耗时和更短的opt耗时:
这里把结论分享出来,供参考和交流。
异常类型:app运行时异常 手机型号:已知三星note20出现过 手机系统版本:11 tinker版本:1.9.14.17 gradle版本:无关 是否使用热更新SDK: 无关 系统:无关 堆栈/日志: AbstractMethodError: abstract method "void android.content.pm.PackageManager$DexModuleRegisterCallback.onDexModuleRegistered"
经过分析,相关代码位置:
private static void registerDexModule(Context context, String dexPath, String oatPath) throws IllegalStateException { try { ... for(int i = 0; i < 2; ++i) { ... try { registerDexModuleMethod.invoke(syncPM, dexPath, new DexModuleRegisterCallback() { public void onDexModuleRegistered(String dexModulePath, boolean success, String message) { ShareTinkerLog.i("Tinker.ParallelDex", "[+] onDexModuleRegistered, path: %s, is_success: %s, msg: %s", new Object[]{dexModulePath, success, message}); } });
onDexModuleRegistered方法被proguard干掉了。一些机型虽然不会crash,但“onDexModuleRegistered”日志不会打印,也可以证明该方法被干掉了。
onDexModuleRegistered
“被proguard干掉”问题在tinker的demo上验证可以重现,问题原因是混淆例外规则配置有误,经实验,以下配置方法可解决问题,供参考和交流:
# 有效 -keepclasseswithmembers class * { ... onDexModuleRegistered(...); } # 有效 -keepclasseswithmembers class com.tencent.tinker.loader.** { ... onDexModuleRegistered(...); } # 有效 -keepclassmembers class com.tencent.tinker.loader.** { ... onDexModuleRegistered(...); }
关于PMDexOpt
triggerPMDexOptOnDemand内部采用了两种突破opt策略:performDexOptSecondary 和 registerDexModule。近期用下面的实验方法做了一次线上灰度实验,得到的结论是绝大部分厂商或机型上registerDexModule能获得更短的补丁加载耗时和更短的opt耗时:
这里把结论分享出来,供参考和交流。
onDexModuleRegistered被混淆干掉了
经过分析,相关代码位置:
onDexModuleRegistered
方法被proguard干掉了。一些机型虽然不会crash,但“onDexModuleRegistered”日志不会打印,也可以证明该方法被干掉了。“被proguard干掉”问题在tinker的demo上验证可以重现,问题原因是混淆例外规则配置有误,经实验,以下配置方法可解决问题,供参考和交流: