美文网首页
关闭Tinker Gradle 编译插件后 Android 5.

关闭Tinker Gradle 编译插件后 Android 5.

作者: sanfen | 来源:发表于2017-10-27 10:31 被阅读476次

    [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 {
        <init>(...);
        void onBaseContextAttached(android.content.Context);
    }
    -keep public class * extends com.tencent.tinker.loader.TinkerLoader {
        <init>(...);
    }
    -keep public class * extends android.app.Application {
         <init>();
         void attachBaseContext(android.content.Context);
    }
    -keep class com.tencent.tinker.loader.TinkerTestAndroidNClassLoader {
        <init>(...);
    }
    -keep class com.iflytek.elpmobile.smartlearning.ThisApplication {
        <init>(...);
    }
    -keep class com.tencent.tinker.loader.** {
             <init>(...);
    }
    
    

    相关文章

      网友评论

          本文标题:关闭Tinker Gradle 编译插件后 Android 5.

          本文链接:https://www.haomeiwen.com/subject/ykrrpxtx.html