不用重新安装修复BUG之Tinker热修复

Tinker是腾讯推出的一个热修复的SDK,目前看来,很好用。Tinker可以使用它提供的后台,也可以不使用,本文没有使用Tinker的后台。要使用Tinker,其实还有很多要注意的地方。Tinker的文档很多,理解透彻也很难,不适合理解能力差的开发者。本文不教你Tinker的基本用法,基本用法参考https://github.com/Tencent/tinker/wiki/Tinker-%E6%8E%A5%E5%85%A5%E6%8C%87%E5%8D%97。本文要教你需要注意哪些地方。

1.TINKER_ID,它是作为基准包的标识的,比如旧版本的包(即安装在手机的包)和新旧版本包的补丁,它们的TINKER_ID应该是一样的,它内部是根据它完成修复的。

2.需要配置

javaCompileOptions {
    //Tinker需要
    annotationProcessorOptions {
        includeCompileClasspath = true
    }
}

3.Tinker的混淆是必须的,否则会修复失败

multiDexKeepProguard file("tinker_multidexkeep.pro")

4.修复的补丁是覆盖的

比如A+补丁B,会换成A+补丁C,而不是A+B+C

 

5.什么情况可以修复,什么情况不可以修复

(1)可以新增普通的Java方法,不带res资源
(2)可以删除普通的Java方法,不带res资源
(3)可以修改普通的Java方法,不带res资源
(4)不可以在清单文件新增组件,如Activity
(5)基准包中使用了tools:replace="android:label”,而第三方库中带有AndroidManife.xml中没有要求替换,会修复失败,通常是第三方库没有删除掉app模块导致的
(6)第三方库minSdk大于基准包的minSdk,会修复失败

 

下面给你介绍几个关键类的写法。

class MusicApp(private val application: Application?) : Application(), AppConfig {

    /**
     * 全局的音乐播放控制管理器。
     */
    var mediaManager: MediaManager? = null
        private set

    /**
     * 内存泄漏检测。
     */
    private var refWatcher: RefWatcher? = null

    companion object {

        /**
         * 全局Application单例。
         */
        @JvmStatic
        var instance: MusicApp? = null
            private set
    }

    override fun attachBaseContext(base: Context) {
        super.attachBaseContext(base)
        //dex分包
        MultiDex.install(base)
    }

}

原自定义的Application要组合一个Application类,这个传入的Application来自Tinker自动生成的。这样你在你的自定义Application也可以拿到Context。

 

package site.doramusic.app.tinker

import android.annotation.TargetApi
import android.app.Application
import android.content.Context
import android.content.Intent
import android.os.Build
import androidx.multidex.MultiDex
import com.tencent.tinker.anno.DefaultLifeCycle
import com.tencent.tinker.entry.DefaultApplicationLike
import com.tencent.tinker.lib.tinker.Tinker
import com.tencent.tinker.lib.tinker.TinkerInstaller
import com.tencent.tinker.loader.shareutil.ShareConstants
import site.doramusic.app.MusicApp
import site.doramusic.app.base.conf.AppConfig
import site.doramusic.app.tinker.log.TinkerLog
import site.doramusic.app.tinker.util.TinkerManager

/**
 * because you can not use any other class in your application, we need to
 * move your implement of Application to [ApplicationLifeCycle]
 * As Application, all its direct reference class should be in the main dex.
 *
 * We use tinker-android-anno to make sure all your classes can be patched.
 *
 * application: if it is start with '.', we will add SampleApplicationLifeCycle's package name
 *
 * flags:
 * TINKER_ENABLE_ALL: support dex, lib and resource
 * TINKER_DEX_MASK: just support dex
 * TINKER_NATIVE_LIBRARY_MASK: just support lib
 * TINKER_RESOURCE_MASK: just support resource
 *
 * loaderClass: define the tinker loader class, we can just use the default TinkerLoader
 *
 * loadVerifyFlag: whether check files' md5 on the load time, defualt it is false.
 *
 */
@DefaultLifeCycle(application = "site.doramusic.app.AppLoader", flags = ShareConstants
                .TINKER_ENABLE_ALL, loadVerifyFlag = false)
class TinkerApplicationLike(application: Application, tinkerFlags: Int, tinkerLoadVerifyFlag: Boolean,
                            applicationStartElapsedTime: Long, applicationStartMillisTime: Long,
                            tinkerResultIntent: Intent?) : DefaultApplicationLike(application, tinkerFlags,
        tinkerLoadVerifyFlag, applicationStartElapsedTime, applicationStartMillisTime, tinkerResultIntent) {

    private var musicApp: MusicApp? = null

    init {
        musicApp = MusicApp(application)
    }

    override fun onCreate() {
        super.onCreate()
        musicApp!!.onCreate()
    }

    /**
     * install multiDex before install tinker
     * so we don't need to put the tinker lib classes in the main dex
     *
     * @param base
     */
    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    override fun onBaseContextAttached(base: Context) {
        super.onBaseContextAttached(base)
        MultiDex.install(base)
        TinkerManager.setTinkerApplicationLike(this)
        TinkerManager.initFastCrashProtect()
        TinkerManager.setUpgradeRetryEnable(true)
        TinkerInstaller.setLogIml(TinkerLog())
        TinkerManager.installTinker(this)
        TinkerManager.loadPatch(AppConfig.FOLDER_PATCH + "/patch_signed.apk")
        Tinker.with(application)
    }
}

这个Tinker的ApplicationLike用来生成Application,那个Tinker的Application入口。其他类使用Tinker官方Demo的代码就可以了。

最后注意一点,所有在你原先自定义Application的所有用到this拿上下文的地方,都要使用传入的这个,即Tinker生成的Application。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dora丶Android

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值