腾讯Bugly热更新的2022年接入记录

1,911 阅读7分钟

产品想要接入热修复功能、又不想自研进行差分包下发管理加大研发周期。故尝试对buyly提供的热修复功能进行接入、对接入过程中的一丢丢问题进行记录 (虽然不是很建议接入 Google play都禁止了)

应用配置信息一览表

minSdkVersion 21
targetSdkVersion 30


classpath 'com.android.tools.build:gradle:3.4.3'
com.tencent.bugly:tinker-support:1.2.1


'androidx.multidex:multidex:2.0.0',
'com.tencent.tinker:tinker-android-lib:1.9.14.10',
"com.tencent.tinker:tinker-android-anno-support:1.9.14.10"
'com.tencent.bugly:crashreport_upgrade:1.5.0'
'com.tencent.bugly:nativecrashreport:3.9.0'


distributionUrl=https://services.gradle.org/distributions/gradle-5.3-bin.zip

查看官方文档

热更新使用指南 - Bugly 文档 (qq.com) 1.0版本的接入文档 挺久没更新了

查看官方Demo

BuglyDevTeam/Bugly-Android-Demo: Bugly Android SDK 使用例子 (github.com) 最近更新时间 2021年6月四日更新

第一步:添加插件依赖

buildscript {
    repositories {
        google()
        jcenter()
        maven { url uri('./repo') }
        maven { url 'https://developer.huawei.com/repo/'}// 友盟
        maven { url  'https://repo1.maven.org/maven2/'}// 友盟
    }
 
    dependencies {
        classpath ('com.tencent.bugly:tinker-support:1.2.1')
    }
}

这里把文档里面的tinker - support 版本从1.1.5 提升到了 1.2.1 (gradle检测到有1.2.3 暂未升)Demo是1.2.0

依据更新日志,发现里面有提到。且在1.1.5打patch包时会报以下错误 (为了解决该问题 还需要其他操作 后续再提 )

更新日志 - Bugly 文档 (qq.com) image.png

第二步:集成SDK

在app module的“build.gradle”文件中添加(示例配置)

android {
    // recommend
    dexOptions {
        jumboMode = true
    }

    kapt {
        // recommend
        correctErrorTypes true
    }

    // 默认配置
    defaultConfig {
        // 开启multidex
        multiDexEnabled true
        ndk {
            // 设置支持的SO库架构
            abiFilters 'x86', 'armeabi-v7a', 'x86_64', 'arm64-v8a'//,'armeabi'
        }
    }
}

dependencies {
 
    // 多dex配置
    implementation 'androidx.multidex:multidex:2.0.0'
 
    // 远程仓库集成方式(推荐)
    implementation 'com.tencent.bugly:crashreport_upgrade:1.5.0'

    implementation 'com.tencent.tinker:tinker-android-lib:1.9.14.10'
    implementation 'com.tencent.bugly:nativecrashreport:3.9.0'
    // walle(多渠道使用)
    // compile 'com.meituan.android.walle:library:1.1.3'
    
    //新增 
    implementation 'com.tencent.tinker:tinker-android-anno-support:1.9.14.10'

}

这里会有一点问题 打包的时候无法找到 tinker.anno 下的文件 。因此 在依赖中新增了anno相关的库 参考 github.com/BuglyDevTea…

在app module的“build.gradle”文件中添加

// 依赖插件脚本
apply from: 'tinker-support.gradle'

注:您需要在同级目录下创建tinker-support.gradle这个文件哦。 这里参考的是官方案例

apply plugin: 'com.tencent.bugly.tinker-support'

def bakPath = file("${buildDir}/bakApk/")

/**
 * 此处填写每次构建生成的基准包目录
 */
def baseApkDir = "app-0518-14-42-00"

/**
 * 对于插件各参数的详细解析请参考,如果没有特殊需求下面的参数都可以不用更改;如果apk需要加固等可以参考具体描述设置参数
 */
tinkerSupport {

    // 开启tinker-support插件,默认值true
    enable = true

    // 指定归档目录,默认值当前module的子目录tinker
    autoBackupApkDir = "${bakPath}"
    //建议设置true,用户就不用再自己管理tinkerId的命名,插件会为每一次构建的base包自动生成唯一的tinkerId,默认命名规则是versionname.versioncode_时间戳
    //具体参考https://github.com/BuglyDevTeam/Bugly-Android-Demo/wiki/Tinker-ID%E8%AF%A5%E6%80%8E%E4%B9%88%E8%AE%BE%E7%BD%AE
    autoGenerateTinkerId = true
    //tinkerId必须保证唯一性,如果两个base包的tinkerid是一样的,并且都联网激活了,那么后续补丁上传到后台的时候会出现匹配错误
    tinkerId = "if autoGenerateTinkerId=true ,no need set here"

    // 是否启用覆盖tinkerPatch配置功能,默认值false
    // 开启后tinkerPatch配置不生效,即无需添加tinkerPatch
    overrideTinkerPatchConfiguration = true

    // 编译补丁包时,必需指定基线版本的apk,默认值为空
    // 如果为空,则表示不是进行补丁包的编译
    // @{link tinkerPatch.oldApk }
    baseApk =  "${bakPath}/${baseApkDir}/app-release.apk"

    // 对应tinker插件applyMapping
    baseApkProguardMapping = "${bakPath}/${baseApkDir}/app-release-mapping.txt"

    // 对应tinker插件applyResourceMapping
    baseApkResourceMapping = "${bakPath}/${baseApkDir}/app-release-R.txt"

//    buildAllFlavorsDir = "${bakPath}/${baseApkDir}"
    // 是否开启加固模式,默认为false
    isProtectedApp = true

    enableProxyApplication = false

    supportHotplugComponent = true

}

/**
 * 一般来说,我们无需对下面的参数做任何的修改
 * 对于各参数的详细介绍请参考:
 * https://github.com/Tencent/tinker/wiki/Tinker-%E6%8E%A5%E5%85%A5%E6%8C%87%E5%8D%97
 */
tinkerPatch {
    //oldApk ="${bakPath}/${appName}/app-debug.apk"
    ignoreWarning = false
    useSign = true
    allowLoaderInAnyDex = true
    removeLoaderForAllDex = true
    dex {
        dexMode = "jar"
        pattern = ["classes*.dex"]
        loader = []
    }
    lib {
        pattern = ["lib/*/*.so"]
    }

    res {
        pattern = ["res/*", "r/*", "assets/*", "resources.arsc", "AndroidManifest.xml"]
        ignoreChange = []
        largeModSize = 100
    }

    packageConfig {
    }
    sevenZip {
        zipArtifact = "com.tencent.mm:SevenZip:1.1.10"
//        path = "/usr/local/bin/7za"
    }
    buildConfig {
        keepDexApply = false
        //tinkerId = "1.0.1-patch"
        //applyMapping = "${bakPath}/${appName}/app-debug-mapping.txt" //  可选,设置mapping文件,建议保持旧apk的proguard混淆方式
        //applyResourceMapping = "${bakPath}/${appName}/app-debug-R.txt" // 可选,设置R.txt文件,通过旧apk文件保持ResId的分配
    }
}

这个文件和官方案例有一点不太一样 在 tinkerPatch{}下 新增了 两行为了解决类不在主dex下问题

allowLoaderInAnyDex = true
removeLoaderForAllDex = true

第三步:初始化SDK

enableProxyApplication = false 的情况 这里采用了官方推荐的方式

  • 自定义Application 因为之前已经有Application了,因此将原有Application 继承 TinkerApplication
public class BaseApplication  extends TinkerApplication {
    public BaseApplication() {
        super(ShareConstants.TINKER_ENABLE_ALL, "com.example.xxxxxxx.hotfix.BaseTinkerApplicationLike",
                "com.tencent.tinker.loader.TinkerLoader", false, true);
    }
}

注意:这个类集成TinkerApplication类,这里面不做任何操作,所有Application的代码都会放到ApplicationLike继承类当中
参数解析
参数1:tinkerFlags 表示Tinker支持的类型 dex only、library only or all suuport,default: > TINKER_ENABLE_ALL
参数2:delegateClassName Application代理类 这里填写你自定义的ApplicationLike
参数3:loaderClassName Tinker的加载器,使用默认即可
参数4:tinkerLoadVerifyFlag 加载dex或者lib是否验证md5,默认为false

  • 将以前的Applicaton配置为继承TinkerApplication的类: 修改AndroidManifest下Application中的
android:name=".app.BaseApplication"
  • 自定义ApplicationLike 在应用的 com.example.xxxxxxx.hotfix目录下创建 BaseTinkerApplicationLike 。要和 上一步自定义Application下super中的内容对应上
public class BaseTinkerApplicationLike extends DefaultApplicationLike {

    public static final String TAG = "Tinker.SampleApplicationLike";

    public BaseTinkerApplicationLike(Application application, int tinkerFlags,
                               boolean tinkerLoadVerifyFlag, long applicationStartElapsedTime,
                               long applicationStartMillisTime, Intent tinkerResultIntent) {
        super(application, tinkerFlags, tinkerLoadVerifyFlag, applicationStartElapsedTime,
                applicationStartMillisTime, tinkerResultIntent);
    }


    @Override
    public void onCreate() {
        super.onCreate();
        // 设置是否开启热更新能力,默认为true
        Beta.enableHotfix = true;
        // 设置是否自动下载补丁,默认为true
        Beta.canAutoDownloadPatch = true;
        // 设置是否自动合成补丁,默认为true
        Beta.canAutoPatch = true;
        // 设置是否提示用户重启,默认为false
        Beta.canNotifyUserRestart = true;
+        // 补丁回调接口 里面的内容看你们的交互
        Beta.betaPatchListener = new BetaPatchListener() {
            @Override
            public void onPatchReceived(String patchFile) {
               // Toast.makeText(getApplication(), "补丁下载地址" + patchFile, Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onDownloadReceived(long savedLength, long totalLength) {
//                Toast.makeText(getApplication(),
//                        String.format(Locale.getDefault(), "%s %d%%",
//                                Beta.strNotificationDownloading,
//                                (int) (totalLength == 0 ? 0 : savedLength * 100 / totalLength)),
//                        Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onDownloadSuccess(String msg) {
                //Toast.makeText(getApplication(), "补丁下载成功", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onDownloadFailure(String msg) {
                //Toast.makeText(getApplication(), "补丁下载失败", Toast.LENGTH_SHORT).show();

            }

            @Override
            public void onApplySuccess(String msg) {
                //Toast.makeText(getApplication(), "补丁应用成功", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onApplyFailure(String msg) {
                //Toast.makeText(getApplication(), "补丁应用失败", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onPatchRollback() {

            }
        };

        // 设置开发设备,默认为false,上传补丁如果下发范围指定为“开发设备”,需要调用此接口来标识开发设备
        Bugly.setIsDevelopmentDevice(getApplication(), true);
        // 多渠道需求塞入
        // String channel = WalleChannelReader.getChannel(getApplication());
        // Bugly.setAppChannel(getApplication(), channel);
        // 这里实现SDK初始化,appId替换成你的在Bugly平台申请的appId
-        Bugly.init(getApplication(), "xxxxxxxxxxx", true);
+        //原来Application下的代码 放在这里 我这里 延后了SDK初始化 
+        //XXXXXXXXX.XXXXXXXX.XXXX(getApplication());
        
    }


    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    @Override
    public void onBaseContextAttached(Context base) {
        super.onBaseContextAttached(base);
        // you must install multiDex whatever tinker is installed!
        MultiDex.install(base);

        // TODO: 安装tinker
        Beta.installTinker(this);
    }

    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    public void registerActivityLifecycleCallback(
            Application.ActivityLifecycleCallbacks callbacks) {
        getApplication().registerActivityLifecycleCallbacks(callbacks);
    }

    @Override
    public void onTerminate() {
        super.onTerminate();
        Beta.unInit();
    }
}

注意:tinker需要你开启MultiDex,你需要在dependencies中进行配置compile "com.android.support:multidex:1.0.1"才可以使用MultiDex.install方法; SampleApplicationLike这个类是Application的代理类,以前所有在Application的实现必须要全部拷贝到这里,在onCreate方法调用SDK的初始化方法,在onBaseContextAttached中调用Beta.installTinker(this);

第四步:AndroidManifest.xml配置

  • 1. 权限配置
<!--Bugly升级SDK权限配置开始-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>

<!--Bugly升级SDK权限配置结束-->

-2. Activity配置

<!-- Bugly升级SDK配置开始  -->
<activity
        android:name="com.tencent.bugly.beta.ui.BetaActivity"
        android:configChanges="keyboardHidden|orientation|screenSize|locale"
        android:theme="@android:style/Theme.Translucent"/>
  • 3. 配置FileProvider
<!--API 24以上配置-->
<provider
        android:name="androidx.core.content.FileProvider"
        android:authorities="com.tencent.bugly.hotfix.fileProvider"
        android:exported="false"
        android:grantUriPermissions="true">
    <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/provider_paths"/>
</provider>

在res目录新建xml文件夹,创建provider_paths.xml文件如下:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- /storage/emulated/0/Download/com.bugly.upgrade.demo/.beta/apk-->
    <external-path name="beta_external_path" path="Download/"/>
    <!--/storage/emulated/0/Android/data/com.bugly.upgrade.demo/files/apk/-->
    <external-path name="beta_external_files_path" path="Android/data/"/>
</paths>

这里配置的两个外部存储路径是升级SDK下载的文件可能存在的路径,一定要按照上面格式配置,不然可能会出现错误。

正常配置如上 但是如果Manifest中 发现使用的第三方库也配置同样的FileProvider, 可以通过继承FileProvider类来解决合并冲突的问题,示例如下:

<provider
    android:name=".util.XXXXProvider"
    android:authorities="${applicationId}.fileProvider"
    android:exported="false"
    android:grantUriPermissions="true"
    tools:replace="name,authorities,exported,grantUriPermissions">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/provider_paths"
        tools:replace="name,resource"/>
</provider>

XXXXProvider

class XXXXProvider: FileProvider()

第五步:混淆配置

-dontwarn com.tencent.bugly.**
-keep public class com.tencent.bugly.**{*;}
# tinker混淆规则
-dontwarn com.tencent.tinker.**
-keep class com.tencent.tinker.** { *; }
-keep class android.support.**{*;}


# 加了 Annotation 添加一些 Annotation混淆
-keepattributes *Annotation*
-dontwarn com.tencent.tinker.anno.AnnotationProcessor
-keep @com.tencent.tinker.anno.DefaultLifeCycle public class *
-keep public class * extends android.app.Application {
    *;
}

-keep public class com.tencent.tinker.entry.ApplicationLifeCycle {
    *;
}
-keep public class * implements com.tencent.tinker.entry.ApplicationLifeCycle {
    *;
}

-keep public class com.tencent.tinker.loader.TinkerLoader {
    *;
}
-keep public class * extends com.tencent.tinker.loader.TinkerLoader {
    *;
}

-keep public class com.tencent.tinker.loader.TinkerTestDexLoad {
    *;
}

-keep public class com.tencent.tinker.loader.TinkerTestDexLoad {
    *;
}

-keep public class com.tencent.tinker.entry.TinkerApplicationInlineFence {
    *;
}

#for command line version, we must keep all the loader class to avoid proguard mapping conflict
#your dex.loader pattern here
-keep public class com.tencent.tinker.loader.** {
    *;
}
# 这里留意一下 
-keep class com.xxx.xxxxx.xxxxxx.BaseTinkerApplicationLike {
    *;
}

如果你使用了support-v4包,你还需要配置以下混淆规则:

-keep class android.support.**{*;}

第六步:关闭R8 (推荐)

在gradle.properties 上 关闭R8 即

android.enableR8=false

热更修 流程 梳理

  • 点击assembleReleas image.png

  • 在build 目录下的bakApk 会生成如下目录 里面的内容包含

    • release包
    • mapping文件
    • R文件 记得备份哦

image.png

  • 修复有问题的类 保存

  • 修改tinker-support.gradle 文件 并保存

//这理的路径是你有问题的包的目录 
def baseApkDir = "app-0518-14-42-00"
  • 点击tinker-support task 下的 buildTinkerPatchRelease 执行命令

image.png

  • 会先自动生成以下目录

image.png

  • 并在以下 目录自动生成 差分包

image.png

  • 选择patch_signed_7zip.apk这个差分包在bugly官网进行下发

加固包直接对生成的pakApk目录下的release包进行加固就好了

集成相关问题

Tinker Exception:fail to create inline fence instance

这里的话 是 TinkerApplicationInlineFence 没有分到主Dex里 相关可以阅读 这篇文章 (49条消息) Tinker Exception:fail to create inline fence instance及如何把想要的类放到主Dex里_丶下一个天亮的博客-CSDN博客 以及为方法数超过 64K 的应用启用 MultiDex  |  Android 开发者  |  Android Developers (google.cn) Tinker 官方也有对这个有一些注释及文章

image.png 解决方法具体操作如下 在android{}中新增以下代码

android {
    defaultConfig{
        multiDexEnabled true
        multiDexKeepProguard file("tinker_multidexkeep.pro")
        multiDexKeepFile file("maindexlist.txt")
    }
}

和 Tinker-support.gradle 同一级目录

tinker_multidexkeep.pro 内容

#tinker multidex keep patterns:
-keep public class * implements com.tencent.tinker.entry.ApplicationLifeCycle {
    <init>(...);
    void onBaseContextAttached(android.content.Context);
}

-keep public class com.tencent.tinker.entry.ApplicationLifeCycle {
    *;
}

-keep public class * extends com.tencent.tinker.loader.TinkerLoader {
    <init>(...);
}

-keep public class * extends android.app.Application {
     <init>();
     void attachBaseContext(android.content.Context);
}

#your dex.loader patterns here
-keep class com.xxx.xxxxxxxxx.app.BaseApplication{
    <init>(...);
}
-keep class com.xxx.xxxxxxxxx.hotfix.BaseTinkerApplicationLike {
    <init>(...);
}

-keep class com.tencent.tinker.loader.** {
    <init>(...);
}

-keep class android.support.test.internal** { *; }
-keep class org.junit.** { *; }

maindexlist.txt 内容

com/tencent/tinker/entry/TinkerApplicationInlineFence.class
+//你的Application类 
+com/xxxxxxxxxx/xxxxxxxxx/app/BaseApplication.class
+//你的ApplicationLike类 
+com/xxxx/xxxxxxxxxxxxxx/hotfix/BaseTinkerApplicationLike.class

com/tencent/tinker/loader/shareutil/ShareResPatchInfo.class
com/tencent/tinker/loader/SystemClassLoaderAdder$V23.class
com/tencent/tinker/loader/hotplug/ActivityStubManager.class
com/tencent/tinker/loader/shareutil/ShareOatUtil$1.class
com/tencent/tinker/loader/shareutil/ShareOatUtil.class
com/tencent/tinker/loader/shareutil/SharePatchFileUtil.class
com/tencent/tinker/loader/shareutil/ShareFileLockHelper.class
com/tencent/tinker/loader/hotplug/ActivityStubs$SGTKStub_04.class
com/tencent/tinker/loader/TinkerDexOptimizer$StreamConsumer$1.class
com/tencent/tinker/loader/TinkerDexLoader.class
com/tencent/tinker/loader/hotplug/ActivityStubs$STDStub_06.class
com/tencent/tinker/loader/TinkerDexOptimizer$1.class
com/tencent/tinker/loader/TinkerDexOptimizer$StreamConsumer.class
com/tencent/tinker/loader/hotplug/IncrementComponentManager.class
com/tencent/tinker/loader/AndroidNClassLoader.class
com/tencent/tinker/loader/TinkerResourcesKey.class
com/tencent/tinker/loader/hotplug/ActivityStubs$SIStub_09.class
com/tencent/tinker/loader/hotplug/interceptor/ServiceBinderInterceptor.class
com/tencent/tinker/loader/hotplug/ActivityStubs$SGTStub_07.class
com/tencent/tinker/loader/shareutil/ShareIntentUtil.class
com/tencent/tinker/loader/hotplug/ActivityStubs$SIStub_00.class
com/tencent/tinker/loader/TinkerResourcesKey$V24.class
com/tencent/tinker/loader/hotplug/ActivityStubs$SGTKStub_05.class
com/tencent/tinker/loader/TinkerTestAndroidNClassLoader.class
com/tencent/tinker/loader/hotplug/ActivityStubs$STDStub_01_T.class
com/tencent/tinker/loader/hotplug/ActivityStubs$SIStub_01_T.class
com/tencent/tinker/loader/hotplug/ActivityStubs$SGTStub_01_T.class
com/tencent/tinker/loader/hotplug/ActivityStubs$STDStub_07.class
com/tencent/tinker/loader/hotplug/ActivityStubs$SGTKStub_00_T.class
com/tencent/tinker/loader/hotplug/handler/MHMessageHandler.class
com/tencent/tinker/loader/shareutil/ShareElfFile$SectionHeader.class
com/tencent/tinker/loader/TinkerDexOptimizer$ResultCallback.class
com/tencent/tinker/loader/TinkerResourceLoader.class
com/tencent/tinker/loader/SystemClassLoaderAdder$V19.class
com/tencent/tinker/loader/hotplug/ActivityStubs$SGTStub_06.class
com/tencent/tinker/loader/hotplug/interceptor/ServiceBinderInterceptor$1.class
com/tencent/tinker/loader/hotplug/ActivityStubs$SIStub_08.class
com/tencent/tinker/loader/hotplug/interceptor/ServiceBinderInterceptor$BinderInvocationHandler.class
com/tencent/tinker/loader/shareutil/ShareResPatchInfo$LargeModeInfo.class
com/tencent/tinker/loader/hotplug/ActivityStubs.class
com/tencent/tinker/loader/hotplug/interceptor/TinkerHackInstrumentation.class
com/tencent/tinker/loader/TinkerResourcesKey$V19.class
com/tencent/tinker/loader/hotplug/ActivityStubs$SGTKStub_02.class
com/tencent/tinker/loader/hotplug/ActivityStubs$SGTStub_09.class
com/tencent/tinker/loader/hotplug/ActivityStubs$STDStub_00.class
com/tencent/tinker/loader/shareutil/ShareElfFile$1.class
com/tencent/tinker/loader/hotplug/ActivityStubs$STDStub_02_T.class
com/tencent/tinker/loader/TinkerTestDexLoad.class
com/tencent/tinker/loader/shareutil/ShareElfFile$ProgramHeader.class
com/tencent/tinker/loader/TinkerSoLoader.class
com/tencent/tinker/loader/hotplug/interceptor/HandlerMessageInterceptor$CallbackWrapper.class
com/tencent/tinker/loader/hotplug/ActivityStubs$SGTKStub_01_T.class
com/tencent/tinker/loader/hotplug/ActivityStubs$STDStub_08.class
com/tencent/tinker/loader/shareutil/ShareElfFile$ElfHeader.class
com/tencent/tinker/loader/TinkerResourcePatcher.class
com/tencent/tinker/loader/shareutil/ShareTinkerInternals.class
com/tencent/tinker/loader/hotplug/ComponentHotplug.class
com/tencent/tinker/loader/hotplug/ActivityStubs$SIStub_07.class
com/tencent/tinker/loader/TinkerDexOptimizer$OptimizeWorker.class
com/tencent/tinker/loader/hotplug/interceptor/InterceptFailedException.class
com/tencent/tinker/loader/hotplug/ActivityStubs$SGTStub_01.class
com/tencent/tinker/loader/BuildConfig.class
com/tencent/tinker/loader/TinkerLoader.class
com/tencent/tinker/loader/hotplug/ActivityStubs$SGTKStub_03.class
com/tencent/tinker/loader/hotplug/ActivityStubs$STDStub_01.class
com/tencent/tinker/loader/SystemClassLoaderAdder$V4.class
com/tencent/tinker/loader/hotplug/interceptor/Interceptor$ITinkerHotplugProxy.class
com/tencent/tinker/loader/shareutil/ShareSecurityCheck.class
com/tencent/tinker/loader/hotplug/ActivityStubs$STDStub_09.class
com/tencent/tinker/loader/hotplug/ActivityStubs$SGTStub_00.class
com/tencent/tinker/loader/hotplug/interceptor/ServiceBinderInterceptor$FakeInterfaceHandler.class
com/tencent/tinker/loader/SystemClassLoaderAdder.class
com/tencent/tinker/loader/hotplug/ActivityStubs$SGTStub_08.class
com/tencent/tinker/loader/hotplug/ActivityStubs$SIStub_06.class
com/tencent/tinker/loader/TinkerResourcesKey$V17.class
com/tencent/tinker/loader/hotplug/ActivityStubs$SGTKStub_00.class
com/tencent/tinker/loader/hotplug/interceptor/HandlerMessageInterceptor.class
com/tencent/tinker/loader/shareutil/ShareBsDiffPatchInfo.class
com/tencent/tinker/loader/shareutil/ShareReflectUtil.class
com/tencent/tinker/loader/hotplug/ActivityStubs$SGTStub_00_T.class
com/tencent/tinker/loader/hotplug/ActivityStubs$STDStub_00_T.class
com/tencent/tinker/loader/hotplug/ActivityStubs$STDStub_02.class
com/tencent/tinker/loader/TinkerUncaughtHandler.class
com/tencent/tinker/loader/hotplug/ActivityStubs$SIStub_02_T.class
com/tencent/tinker/loader/TinkerDexOptimizer.class
com/tencent/tinker/loader/shareutil/ShareConstants.class
com/tencent/tinker/loader/shareutil/SharePatchInfo.class
com/tencent/tinker/loader/hotplug/ActivityStubs$SGTKStub_09.class
com/tencent/tinker/loader/hotplug/handler/PMSInterceptHandler.class
com/tencent/tinker/loader/hotplug/ActivityStubs$SIStub_05.class
com/tencent/tinker/loader/hotplug/ActivityStubs$SGTStub_03.class
com/tencent/tinker/loader/hotplug/ActivityStubs$SGTKStub_01.class
com/tencent/tinker/loader/SystemClassLoaderAdder$V14.class
com/tencent/tinker/loader/hotplug/ActivityStubs$STDStub_03.class
com/tencent/tinker/loader/hotplug/IncrementComponentManager$AttrTranslator.class
com/tencent/tinker/loader/shareutil/ShareOatUtil$InstructionSet.class
com/tencent/tinker/loader/app/TinkerApplication.class
com/tencent/tinker/loader/hotplug/interceptor/ServiceBinderInterceptor$FakeClientBinderHandler.class
com/tencent/tinker/loader/hotplug/ActivityStubs$SGTStub_02.class
com/tencent/tinker/loader/hotplug/UnsupportedEnvironmentException.class
com/tencent/tinker/loader/TinkerRuntimeException.class
com/tencent/tinker/loader/hotplug/ActivityStubs$SIStub_04.class
com/tencent/tinker/loader/hotplug/interceptor/HandlerMessageInterceptor$MessageHandler.class
com/tencent/tinker/loader/hotplug/ActivityStubs$SGTKStub_06.class
com/tencent/tinker/loader/TinkerDexLoader$1.class
com/tencent/tinker/loader/hotplug/ActivityStubs$SIStub_00_T.class
com/tencent/tinker/loader/hotplug/ActivityStubs$SGTStub_02_T.class
com/tencent/tinker/loader/hotplug/ActivityStubs$STDStub_04.class
com/tencent/tinker/loader/hotplug/IncrementComponentManager$1.class
com/tencent/tinker/loader/hotplug/EnvConsts.class
com/tencent/tinker/loader/hotplug/handler/AMSInterceptHandler.class
com/tencent/tinker/loader/hotplug/ActivityStubs$SGTStub_05.class
com/tencent/tinker/loader/hotplug/ActivityStubs$SIStub_03.class
com/tencent/tinker/loader/hotplug/ActivityStubs$SIStub_02.class
com/tencent/tinker/loader/hotplug/ActivityStubs$SGTKStub_07.class
com/tencent/tinker/loader/hotplug/ActivityStubs$STDStub_05.class
com/tencent/tinker/loader/AbstractTinkerLoader.class
com/tencent/tinker/loader/hotplug/ActivityStubs$SGTKStub_02_T.class
com/tencent/tinker/loader/SystemClassLoaderAdder$1.class
com/tencent/tinker/loader/TinkerResourcesKey$V7.class
com/tencent/tinker/loader/shareutil/ShareDexDiffPatchInfo.class
com/tencent/tinker/loader/shareutil/ShareElfFile.class
com/tencent/tinker/loader/hotplug/ActivityStubs$SGTKStub_08.class
com/tencent/tinker/loader/hotplug/ActivityStubs$SGTStub_04.class
com/tencent/tinker/loader/hotplug/interceptor/Interceptor.class
com/tencent/tinker/loader/hotplug/ActivityStubs$SIStub_01.class
com/tencent/tinker/build/decoder/ApkDecoder.class
com/tencent/tinker/build/patch/Runner.class
com/tencent/tinker/loader/R.class

打差分包的时候会出现 loader classes are found in old secondary dex. Found classes:

ignoreWarning is false, but we found loader classes are found in old secondary dex

然后在tinker 和 bugly的 issue 中 找到了 以下相关文章

Warning:ignoreWarning is false, but we found loader classes are found in old secondary dex. Found classes: · Issue #1420 · Tencent/tinker (github.com)

解决方式

tinker-support.gradle 文件上新增以下代码

tinkerPatch {
  
+    allowLoaderInAnyDex = true
+    removeLoaderForAllDex = true
  
}

Illegal invoke-super to void androidx.appcompat.widget.AbsActionBarView.onDetachedFromWindow() from class androidx.appcompat.widget.ActionBarContextView

TinkerPatchException:调用了没有加载的类XmlPullParser导致打补丁包失败 · Issue #1580 · Tencent/tinker (github.com)

解决方式

然后在gradle.properties 上 关闭R8 即

android.enableR8=false