Tinker热修复

399 阅读1分钟

Tinker是一款优秀的热修复框架,它是基于TINKER_ID来对基准包进行修复的,比如旧版本的包(即安装在手机的包)和新旧版本包的补丁,它们的TINKER_ID应该是一样的,那么它就可以修复。

配置apt选项

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

代码混淆

multiDexKeepProguard file("tinker_multidexkeep.pro")

修复逻辑

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

关键类

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

    var mediaManager: MediaManager? = null 
        private set 
    private var refWatcher: RefWatcher? = null 
    
    companion object { 
        @JvmStatic var instance: MusicApp? = null 
            private set 
    }
    
    override fun attachBaseContext(base: Context) {
        super.attachBaseContext(base) 
        //dex分包 
        MultiDex.install(base) 
    }
}
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) 
     } 
 }

具体还参考github.com/Tencent/tin…