Tinker集成和遇坑總結

1.tinker集成步驟

  1. 添加依賴
  2. 初始化
  3. 生成補丁
  4. 下發補丁

1.添加依賴

  • 添加project依賴
  • 添加model依賴
  • 添加tinkerPatch.gradle

  添加project依賴:打開項目project的gradle添加以下代碼

buildscript {
    repositories {
        jcenter()
        google()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.2.1'
        // TinkerPatch 插件,添加以下兩行代碼就行
        classpath "com.tinkerpatch.sdk:tinkerpatch-gradle-plugin:1.2.9"
        classpath "com.tencent.bugly:tinker-support:1.1.5"
    }
}

添加model依賴:打開model的gradle文件,如下添加依賴,只需要添加註釋標明部分即可,這裏我是固定使用的1.9.8的tinker

apply plugin: 'com.android.application'
apply from: 'tinkerpatch.gradle'//這裏是需要添加的,這裏是關聯到tinkerpatch.gradle文件,這樣我們就可以單獨在tinkerpatch.gradle配置一切tinker的內容


android {
    compileSdkVersion 26

    defaultConfig {
        applicationId "com.yunmayi.cashier"
        minSdkVersion 19
        targetSdkVersion 26
        versionCode 891
        versionName "1.8.4"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        multiDexEnabled true
        javaCompileOptions { annotationProcessorOptions { includeCompileClasspath = true } }

    }



    buildTypes {
        release {
            minifyEnabled false
            multiDexKeepFile file('multidex-android.txt')
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    sourceSets {
        main {
            jniLibs.srcDirs = ['libs']
        }
    }
    dexOptions {
        jumboMode true
    }

    lintOptions {
        abortOnError false
    }

}

repositories {
    maven {
        url "http://dl.bintray.com/jlmd/maven"
    }
}

dependencies {
    //這裏也是需要添加的,這是熱修復依賴
    annotationProcessor("com.tinkerpatch.tinker:tinker-android-anno:1.9.8")
    compileOnly 'com.tinkerpatch.tinker:tinker-android-anno:1.9.8'
    implementation 'com.tinkerpatch.sdk:tinkerpatch-android-sdk:1.2.8'
}

添加tinkerPatch.gradle:這個步驟就是創建上面gradle依賴的tinkerpatch.gradle文件

第一步:新建一個gradle文件,名字叫做tinkerpatch.gradle,創建完成之後就是這樣子了

第二步寫入tinker配置。這裏直接照抄官方的配置就可以,下面是我自己修改過的,下面圖片是我自己的配置

apply plugin: 'tinkerpatch-support'

def bakPath = file("${buildDir}/bakApk/")//這個是編譯基礎包的位置


tinkerpatchSupport {
    /** 編譯時是否打開tinker(打開的話會在你的build/bakapk中多生成一個apk,同時編譯速度加長)**/
    tinkerEnable = true

    /** 是否使用一鍵接入功能  **/
    reflectApplication = true

    /** 如果用了360加固或者其他之類的加固軟件這個得打開,需要查看tinker官網是否支持你選用的加固工具 **/
    protectedApp = false

    /** 補丁是否支持新增 Activity (exported必須爲false)**/
    supportComponent = false

    autoBackupApkPath = "${bakPath}"

    /** 在tinkerpatch.com得到的appKey **/
    appKey = "應用的appkey"
    /** 注意: 若發佈新的全量包, appVersion一定要更新 **/
    appVersion = "891"//這個對應的是平臺的補丁版本,是指的新建補丁那個版本,建議和應用版本號同步

    /**bakapk目錄下的apk文件
      * 所謂基礎包,是你在生成補丁包時,那個拿來對比的安裝包,務必在出版本的時候保留,
    **/
    baseApkFile = "放置基礎包的路徑"
    /**bakapk目錄下的-mapping.txt文件
      * 當你的應用開啓混淆時會在bakapk和apk同一個目錄下會生成這個文件,不開啓混淆則不會生成
    **/
    baseProguardMappingFile = "放置混淆記錄文件的路徑"

    /**bakapk目錄下的-R.txt文件
      * 在bakapk和apk同一個目錄下會生成這個文件
    **/
    baseResourceRFile = "資源映射文件"
}
/**
 * 用於用戶在代碼中判斷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
    }
}

再貼出一下bakapk的目錄結構

2.初始化

直接在application中的onCreate中執行以下方法

 private void initTinker() {
        /*
         * 我們需要確保至少對主進程跟patch進程初始化 TinkerPatch
         */
        if (BuildConfig.TINKER_ENABLE) {
            // 初始化TinkerPatch SDK, 更多配置可參照API章節中的,初始化SDK
            TinkerPatch.init(mApplicationLike)
                    .setPatchResultCallback(new ResultCallBack() {
                        @Override
                        public void onPatchResult(PatchResult patchResult) {
                            Log.i("patch",patchResult.patchVersion);
                        }
                    })
                    .reflectPatchLibrary()
                    .fetchPatchUpdate(true)
                    .setPatchRollbackOnScreenOff(true)
                    .setPatchRestartOnSrceenOff(true);
            // 每隔3個小時去訪問後臺時候有更新,通過handler實現輪訓的效果
            new FetchPatchHandler().fetchPatchWithInterval(3);
        }
    }

FetchPatchHandler的代碼,主要就是一個定時器:

public class FetchPatchHandler extends Handler {

    public static final long HOUR_INTERVAL = 3600 * 1000;
    private long checkInterval;


    /**
     * 通過handler, 達到按照時間間隔輪訓的效果
     */
    public void fetchPatchWithInterval(int hour) {
        //設置TinkerPatch的時間間隔
        TinkerPatch.with().setFetchPatchIntervalByHours(hour);
        checkInterval = hour * HOUR_INTERVAL;
        //立刻嘗試去訪問,檢查是否有更新
        sendEmptyMessage(0);
    }


    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        //這裏使用false即可
        TinkerPatch.with().fetchPatchUpdate(false);
        //每隔一段時間都去訪問後臺, 增加10分鐘的buffer時間
        sendEmptyMessageDelayed(0, checkInterval + 10 * 60 * 1000);
    }
}

這樣子,項目就配置好了tinker了,接下來是補丁生成和下發的部分。

3.生成補丁

  1. 生成基礎文件(apk,R.txt,maping.txt)
  2. 對比生成補丁

生成基礎文件:

   這個步驟一般在實際項目中發生在出版本的時候,操作如下

執行完成之後會在bakapk目錄下生成一個新的文件夾,裏面包含了三個或者兩個文件,把這幾個文件放置到你tinkerpatch.gradle中配置的那個文件目錄下方,這個apk就是提供給用戶的apk

對比生成補丁,當我們發生bug之後,代碼修改後,此時需要生成補丁上去修復故障,在生成基礎文件的時候我們已經將基礎文件放置到對應目錄下了,那麼接下來直接這麼操作:

在編譯完成之後會打印出如下日誌

find the output 後面那個就是補丁包的生成路徑了,路徑下存在打好的補丁包了

4.下發補丁

這時候打開tinker官網找到自己需要發佈的應用,創建好對應版本,然後選擇文件下發就可以了,這個版本是和tinkerPatch.gradle裏面配置的版本對應的。

遇坑總結

1.tinker上傳補丁包顯示非法

這個問題首先檢查你的補丁包大小是否正確,如果正確把電腦時間同步一下,然後重新構建補丁包,如果還有問題聯繫tinker工作人員處理一下(或者升級付費版,騰訊你懂得),上次我也是碰到這個問題沒理他,過幾天就能夠正常上傳了。

2.tinker修復之後程序直接崩潰

這邊列舉一種我碰到的錯誤:在補丁下發並且合成之後,再次打開程序,直接崩潰,顯示資源未找到異常,這時候請檢查你的補丁包文件夾是否有除了.apk之外的其他文件,如果有恭喜,這個文件通過充錢可以解決,首先說下產生原因:

tinker在生成補丁的時候會把設置的部分進行一個對比,一旦發生改變就會添加到補丁包中,這個是可以配置的,例如你的資源文件發生了改變,那麼會多出一個resource.7z的資源補丁包,這時候在補丁包中指定的資源id就變了,就是R.id.xxx對應的那些R文件的資源變了,這時候你需要上傳兩個補丁一個是資源補丁,一個是代碼補丁,不然會NotFoundException,在AS3.0開啓了aapt2之後,莫名的所有資源都會檢測到修改,這個我也不知道爲啥,所以會生成一個巨大的資源補丁包,這時候官方免費的版本是不能上傳太大文件的(所以如果想修改資源,建議使用付費版)。

重點來了:但是實際中如果你不需要替換資源,又想不交錢,那麼可以指定對比的資源,只修改代碼這時候也是能夠解決問題的

配置tinkerPatch.gradle如下:

/**
 * 一般來說,我們無需對下面的參數做任何的修改
 * 對於各參數的詳細介紹請參考:
 * 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"]
    }

//修改此處,這邊是修改tinker打包資源時對比的資源選項,其中src是默認的,但是資源文件可以按照需
//要自己配置,我這邊配置只對比AndroidMefest.xml的內容,所以我配置的tinker只能修改代碼,這裏按//照自己需要配置
    res {
        pattern = ["AndroidManifest.xml"]
        ignoreChange = ["res/*","r/*", "assets/*", "resources.arsc",]
        largeModSize = 100
    }

    packageConfig {
    }
    sevenZip {
        zipArtifact = "com.tencent.mm:SevenZip:1.1.10"
//        path = "/usr/local/bin/7za"
    }
    buildConfig {
        keepDexApply = false
    }
}

其次在安卓8.0之後3小時一次的輪詢據說失效,我沒測試過,大家可以試試,且又聽說在最新版本的tinker中添加了定時輪詢,沒去了解,小夥伴們可以自己試試。

撒有啦啦!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章