关闭Tinker Gradle 编译插件后 Android 5.0版本以下机型运行Crash分析报告

[toc]

关闭Tinker Gradle 编译插件后 Android 5.0版本以下机型运行Crash分析报告

一、再现场景

集成Tinker并使用tinkerEnabled = false关闭Tinker Gradle 编译插件开关)运行在华为CHM-UL00( Android版本4.4.2)直接crash,根据目前手中测试机测试后,Android版本5.0以下手机都会出现同样的问题,5.0以上均运行正常。

二、错误日志

Caused by: com.tencent.tinker.loader.TinkerRuntimeException: Tinker Exception:createDelegate failed
Tinker.UncaughtHandler: catch exception when loading tinker:java.lang.RuntimeException: Unable to instantiate application com.iflytek.elpmobile.smartlearning.ThisApplication: com.tencent.tinker.loader.TinkerRuntimeException: Tinker Exception:createDelegate failed

三、原因分析

故根据 Android版本5.0前后现象不同和错误日志分析,怀疑问题与分Dex方案Multidex在Android 5.0前后版本引用策略不同有关。经查询:

Multidex支持Android 5.0之前的版本 : Android5.0版本的平台之前,Android使用的是Dalvik Runtime执行的程序代码。默认情况下,限制应用到一个单一的classes.dex。Dalvik字节码文件每APK。为了绕过这个限制,你可以使用multidex支持库,成为你的应用程序的主要部分和DEX文件进行管理,获得额外的dex文件,它们包含的代码。

Multidex支持Android 5.0及更高版本 : Android 5.0和更高的Runtime 如art,本身就支持从应用的APK文件加载多个DEX文件。art支持预编译的应用程序在安装时扫描类(..)。Dex文件编译成一个单一的Android设备上执行.oat文件。

  • Tinker需要确保下述文件放在主dex中:
  1. ApplicationLike实现类以及它的直接引用类
  2. 在调用Multidex install之前加载的类
  3. com.tencent.tinker.loader.*类
  4. 自定义了TinkerLoader类
  • 而关闭tinkerEnabled后,Tinker Gradle 编译插件 中 生成需要放在主dex的keep规则和相关文件混淆的keep规则 的自动处理脚本 均不会执行,所以需要手动配置相关keep规则

四. 解决方案

  • 方案一:打开tinkerEnabled = true,测试均运行正常。
  • 方案二:关闭tinkerEnabled false,并如下手动引入分包策略文件,测试均运行正常,步骤如下:
    1. 首先暂时打开tinkerEnabled = true,使插件生成需要放在主Dex的keep规则。
    2. 然后将app/build/intermediates/tinker_intermediates/tinker_multidexkeep.pro(生成的keep规则文件)拷贝到主Module目录下,在主Module的app build中配置该规则:
    defaultConfig {
        multiDexKeepProguard file("./tinker_multidexkeep.pro")
    }
    

五、keep规则

#tinker multidex keep patterns:
#proguardFiles adds
-keep public class * implements com.tencent.tinker.loader.app.ApplicationLifeCycle {
    (...);
    void onBaseContextAttached(android.content.Context);
}
-keep public class * extends com.tencent.tinker.loader.TinkerLoader {
    (...);
}
-keep public class * extends android.app.Application {
     ();
     void attachBaseContext(android.content.Context);
}
-keep class com.tencent.tinker.loader.TinkerTestAndroidNClassLoader {
    (...);
}
-keep class com.iflytek.elpmobile.smartlearning.ThisApplication {
    (...);
}
-keep class com.tencent.tinker.loader.** {
         (...);
}

你可能感兴趣的:(关闭Tinker Gradle 编译插件后 Android 5.0版本以下机型运行Crash分析报告)