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中添加了定时轮询,没去了解,小伙伴们可以自己试试。

撒有啦啦!!!

展开阅读全文

没有更多推荐了,返回首页