Android熱更新利器Tinker接入

參考

騰訊Tinker官方文檔

建議大家先使用demo實驗,成功后再集成到真正項目中。。。因為。。。你懂的!!!

寫在前面

好久沒有寫博客了,都用筆記的形式記錄了所學的東西。最近面試跟面試官聊起,發現寫博客真的是一個好習慣,希望堅持下去吧。本文的目的就一個,讓應用接入Tinker熱更新,我們不去探究這東西怎么實現,本文僅僅作為工具使用指南。
類似的原理性文章可以參考下拙作:
Android黑科技動態加載(一)之Java中的ClassLoader
Android黑科技動態加載(二)之Android中的ClassLoader
Android黑科技動態加載(三)之動態加載資源
Android黑科技動態加載(四)之插件化開發

基準包

例如有一個版本A,但是這時A是有Bug的,然后修復Bug后的生成的版本我們稱為B。A和B之間的區別產生一個差分包(這里也稱為補丁包),那么我們就可以說這個差分包是以A作為基準包相對B生成的。參考增量更新文章:Android NDK開發兩部曲(二)之應用篇(增量更新也就那樣)

基本步驟

1、注冊Tinker賬號并新建項目,傳送門
2、配置gradle和代碼
3、生成基準包
4、修復Bug
5、生成補丁包
6、發布補丁包

Tinker做了什么

1、1-2步是APP開發的基本步驟,完成1-3步,那么你的APP就集成了Tinker。
集成Tinker后,Tinker會根據各個版本的配置信息去自動加載補丁。可配置強制更新,也可配置輪詢更新。

2、第3步則是保留一個之前版本副本,用于后面生成補丁。為什么要這樣做?因為1.0.2的相對于1.0.1的補丁包只能作用在1.0.1版本上。如果想要處理1.0.0那么有兩種方法,使用1.0.0->1.0.1和1.0.1->1.0.2兩個補丁包。但是也可以生成1.0.0->1.0.2的補丁包。所以副本保留還是有必要的。
3、4-6部就是真正應用到生產環境上了,真正達到熱修復的作用。

一、注冊Tinker賬號

這個就不說了,Tinker注冊和新建項目都好簡單,也沒有什么需要注意的。拿到appKey

二、配置Gradle和代碼

這個推薦我們的拷貝粘貼代碼

1、配置Tinker版本信息

我們使用配置文件去配置版本信息,易于統一版本和后面更換版本
編輯根目錄的gradle.properties,加入

TINKER_VERSION=1.9.2
TINKERPATCH_VERSION=1.2.2

2、配置根目錄下的build.gradle文件

使用Tinker插件

classpath "com.tinkerpatch.sdk:tinkerpatch-gradle-plugin:${TINKERPATCH_VERSION}"

3、配置Tinker的gradle腳本

在項目根目錄新建tinkerpatch.gradle文件

apply plugin: 'tinkerpatch-support'

/**
 * TODO: 請按自己的需求修改為適應自己工程的參數
 */
def bakPath = file("${buildDir}/bakApk/")
def baseInfo = "app-1.0.0-1213-19-52-36"
def variantName = "release"

/**
 * 對于插件各參數的詳細解析請參考
 * http://tinkerpatch.com/Docs/SDK
 */
tinkerpatchSupport {
    /** 可以在debug的時候關閉 tinkerPatch **/
    /** 當disable tinker的時候需要添加multiDexKeepProguard和proguardFiles,
        這些配置文件本身由tinkerPatch的插件自動添加,當你disable后需要手動添加
        你可以copy本示例中的proguardRules.pro和tinkerMultidexKeep.pro,
        需要你手動修改'tinker.sample.android.app'本示例的包名為你自己的包名, com.xxx前綴的包名不用修改
     **/
    tinkerEnable = true
    reflectApplication = true
    /**
     * 是否開啟加固模式,只能在APK將要進行加固時使用,否則會patch失敗。
     * 如果只在某個渠道使用了加固,可使用多flavors配置
     **/
    protectedApp = false
    /**
     * 實驗功能
     * 補丁是否支持新增 Activity (新增Activity的exported屬性必須為false)
     **/
    supportComponent = true

    autoBackupApkPath = "${bakPath}"

    appKey = "c6a00cf4aafa2ab2"

    /** 注意: 若發布新的全量包, appVersion一定要更新 **/
    appVersion = "1.0.0"

    def pathPrefix = "${bakPath}/${baseInfo}/${variantName}/"
    def name = "${project.name}-${variantName}"

    baseApkFile = "${pathPrefix}/${name}.apk"
    baseProguardMappingFile = "${pathPrefix}/${name}-mapping.txt"
    baseResourceRFile = "${pathPrefix}/${name}-R.txt"

    /**
     *  若有編譯多flavors需求, 可以參照: https://github.com/TinkerPatch/tinkerpatch-flavors-sample
     *  注意: 除非你不同的flavor代碼是不一樣的,不然建議采用zip comment或者文件方式生成渠道信息(相關工具:walle 或者 packer-ng)
     **/
}

/**
 * 用于用戶在代碼中判斷tinkerPatch是否被使能
 */
android {
    defaultConfig {
        buildConfigField "boolean", "TINKER_ENABLE", "${tinkerpatchSupport.tinkerEnable}"
    }
}

/**
 * 一般來說,我們無需對下面的參數做任何的修改
 * 對于各參數的詳細介紹請參考:
 * https://github.com/Tencent/tinker/wiki/Tinker-%E6%8E%A5%E5%85%A5%E6%8C%87%E5%8D%97
 */
tinkerPatch {
    ignoreWarning = false
    useSign = 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
    }
}

注意幾個字段內容,主要是后面生成補丁需要用到的,除了AppKey外其他暫時不用改
baseInfo : 這個是基準包的名稱,使用Tinker腳本編譯在模塊的build/bakApk生成編譯副本
variantName : 這個一般對應buildTypes里面你基準包生成的類型,release、debug或其他
appKey : 這個就是Tinker新建項目時拿到的appKey
appVersion : 配置和Tinker后臺新建補丁包的一致

4、配置模塊下的buidle.gradle

A、配置應用簽名

這個百度搜都有,大概就這樣

    signingConfigs {
        release {//發布版本的簽名配置
            storeFile file('key.jks')
            keyAlias 'test'
            storePassword '123456789'
            keyPassword '123456789'
        }
        debug {//調試版本的簽名配置
            storeFile file('key.jks')
            keyAlias 'test'
            storePassword '123456789'
            keyPassword '123456789'
        }
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.release
        }
        debug {
            signingConfig signingConfigs.debug
        }
    }

B、配置依賴

 //若使用annotation需要單獨引用,對于tinker的其他庫都無需再引用
        annotationProcessor("com.tinkerpatch.tinker:tinker-android-anno:${TINKER_VERSION}") {
            changing = true
        }
        compileOnly("com.tinkerpatch.tinker:tinker-android-anno:${TINKER_VERSION}") {
            changing = true
        }
        implementation("com.tinkerpatch.sdk:tinkerpatch-android-sdk:${TINKERPATCH_VERSION}") {
            changing = true
        }

C、使用插件

在模塊的build.gradle加入

apply from: 'tinkerpatch.gradle'

3、代碼配置

最后一步配置,把代碼集成到App里,別忘了在AndroidManifest里面配置APP。。。

public class App extends Application {
    private ApplicationLike tinkerApplicationLike;

    @Override
    public void onCreate() {
        super.onCreate();
        tinkerApplicationLike = TinkerPatchApplicationLike.getTinkerPatchApplicationLike();

        // 初始化TinkerPatch SDK, 更多配置可參照API章節中的,初始化SDK
        TinkerPatch.init(tinkerApplicationLike)
                .reflectPatchLibrary()
                .fetchPatchUpdate(true)
        // 強制更新
                .setPatchRollbackOnScreenOff(true)
                .setPatchRestartOnSrceenOff(true)
                .setFetchPatchIntervalByHours(3);

        // 每隔3個小時(通過setFetchPatchIntervalByHours設置)去訪問后臺時候有更新,通過handler實現輪訓的效果
        TinkerPatch.with().fetchPatchUpdateAndPollWithInterval();
    }
}

三、生成基準包

其實到了這里就配置完成了,我們生產一個基準包


生成基準包

雙擊assembleRelease生成成功后安裝模塊/build/outputs/apk/release/app-release.apk就OK了,這時候進去模塊/build/bakApk里面記錄一下類似app-1.0.0-1213-19-52-36的文件名稱,只生成一次基準包,那么就會生成一個。但是如果手賤點太多生成太多的話確定不了剛剛生成的是哪個,那么就選最新那個或者刪掉重新生成基準包,真實環境并不允許這樣搞。。。

安裝包
基準包名稱

四、修復bug

隨便修改點代碼

五、生成補丁包

這時候我們就需要去修改一些tinkerpatch.gradle文件的信息了。
baseInfo :還記得app-1.0.0-1213-19-52-36這個東西嗎?換成自己上面記錄的就OK了
variantName : 因為剛剛我們使用assembleRelease生成的補丁,所以我們只需要使用release就OK了

生成差分包

雙擊TinkerPatchRelease生成差分包,patch_signed_7zip.apk就是補丁包了

補丁包

六、發布補丁包

回到Tinker后臺,選中我們開始新建的項目,補丁下發->添加APP版本。然后上傳剛剛的patch_signed_7zip.apk

發布補丁包

APP開啟強制更新的話那么重啟應用就會更新,否則會通過輪詢去更新。應用重啟才生效。Tinker太強大了,本文目的就是把項目跑通,相信后面的很多功能大家有興趣的話一起發現,一起討論。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。