美文网首页程序员首页投稿(暂停使用,暂停投稿)
【Android】热修复之Tinker的集成与使用

【Android】热修复之Tinker的集成与使用

作者: 半罐子晃 | 来源:发表于2018-02-09 12:21 被阅读119次

    前言

    近年来随着Android用户的爆发式增长,Android应用也逐渐完善,应用再也不是只需要会四大组件就可以满足产品的需求,出现了很多三方的SDK,优秀的类库,还有个性化的插件。热修复在近年来特别hot,下面我们就来介绍一下业界评价最好的热修复之一Tinker!

    我们先来比较一下当下热修复界中的四大天王(分别来自微信,QQ空间,阿里,美团):
    什么是Tinker?

    tinker是微信官方的Android热补丁解决方案,官方是这么概括Tinker的:Tinker is a hot-fix solution library for Android, it supports dex, library and resources update without reinstalling apk。用于给程序打补丁,不需要重新安装,支持动态下发代码、So库以及资源等
    可以说很全面了,不管是Java类、xml布局文件、图片甚至是So库都可以用热修复来修改~
    我们要介绍的是自定义Tinker的集成与使用,需要后台的支持,如果不想这么麻烦,可以尝试TinkerPatch的一键傻瓜式接入,具体的可参考文档TinkerPatch 平台介绍
    这款优秀的热修复的GitHub地址是:https://github.com/Tencent/tinker
    官方文档:http://www.tinkerpatch.com/Docs/intro

    怎样集成Tinker?(自定义Tinker )

    1.设置tinker版本 :
    在gradle.properties文件中 添加tinker版本号,方便以后升级时修改:

     TINKER_VERSION=1.9.1
    

    2.在项目的build.gradle文件中添加依赖:

    dependencies {
    buildscript {
        repositories {
            jcenter()
        }
        dependencies {
            // TinkerPatch 插件
             classpath'com.tencent.tinker:tinker-patch-gradle-plugin:${TINKER_VERSION}’
        }
    }
    

    3.配置app的build.gradle文件
    可以依照 tinker-sample-android 项目的build.gradle文件配置
    https://github.com/Tencent/tinker/tree/master/tinker-sample-android
    注:build.gradle配置文件中记得配置keysotre 密码,如果和debug模式,要将自己电脑的debug.keystore文件复制到app下keystore文件夹中

    • debug.keystore在自己电脑 C:\Users<用户名>.Android\debug.keystore

    在运行demo时可能出现tinkerId未设置问题,这是由于demo中tinkerId为git的版本,当你本地无法获取git的版本时,会报错,
    可以将thinkerId设置为应用的versionName,tinkerId保证其唯一性即可,每次升级app tinkerId也需要更新,继续与versionName保持一致。如下当前App的版本号是5.22:

    def gitSha() {
        try {
    //        String gitRev = 'git rev-parse --short HEAD'.execute(null, project.rootDir).text.trim()
    //        if (gitRev == null) {
    //            throw new GradleException("can't get git rev, you should add git to system path or just input test value, such as 'testTinkerId'")
    //        }
            //设置tinkerId,与versionName一致即可
            return '5.22'
    //        return gitRev
        } catch (Exception e) {
            throw new GradleException("can't get git rev, you should add git to system path or just input test value, such as 'testTinkerId'")
        }
    }
    

    4.添加sd的读写权限

        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
        <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    
    1. 改造Application
      请参考SampleApplicationLike来看!
      将原来自定义的Application子类中的逻辑移动到
      SampleApplicationLike中
      修改Application,然后将Application类继承TinkerApplication.java。`除了构造方法之外,你最好不要引入其他的类,这将导致它们无法通过补丁修改。
    public class SampleApplication extends TinkerApplication {
        public SampleApplication() {
          super(
            //tinkerFlags, tinker支持的类型,dex,library,还是全部都支持!
            ShareConstants.TINKER_ENABLE_ALL,
            //ApplicationLike的实现类,只能传递字符串 
            "tinker.sample.android.app.SampleApplicationLike",
            //Tinker的加载器,一般来说用默认的即可
            "com.tencent.tinker.loader.TinkerLoader",
            //tinkerLoadVerifyFlag, 运行加载时是否校验dex与,ib与res的Md5
            false);
        }  
    }
    
    具体的数值含义:

    为了隐藏你的Application类,我们更加推荐你使用tinker-android-anno在运行时生成你的Application类。这样保证你无法修改你的Application类,不会因为错误操作导致引入更多无法修改的类。

    @DefaultLifeCycle(
    application = ".SampleApplication",                       //application类名
    flags = ShareConstants.TINKER_ENABLE_ALL,                 //tinkerFlags
    loaderClass = "com.tencent.tinker.loader.TinkerLoader",   //loaderClassName, 我们这里使用默认即可!
    loadVerifyFlag = false)                                   //tinkerLoadVerifyFlag
    public class SampleApplicationLike extends DefaultApplicationLike
    

    记得在清单文件中配置application名称:



    一些自定义扩展类
    这些类为我们提供了许多方法
    比如加载补丁时的各种回调函数,详情见文档

    我这里直接采用的demo中的类
    注意其中有个service,在补丁加载成功或失败时会执行 记得在清单文件中配置。
    怎样使用Tinker?
    如果按照demo中app的build.gradle文件配置,那么每次运行或者打包时均会在build/bakApk中生成apk、R.txt、 mapping文件

    每次正式发布版本后需要保存这个包的apk(基准包) R.txt(用于修改了资源文件时打补丁) mapping.txt(如果基准包进行了混淆,打补丁时需要用到)

    制作补丁
    1.修改代码、资源文件 解决bug修复

    2.在app的build.gradle文件中填写基准包的信息 :
    3.运行 命令行: gradlew tinkerPatchRelease 或者 tinkerPatchDebug
    完毕后就得到了补丁包
    4.去自己的后台管理系统传补丁包并开启
    重启应用,使之生效。
    加载补丁的api
    TinkerInstaller.onReceiveUpgradePatch(getApplicationContext(), Environment.getExternalStorageDirectory().getAbsolutePath() + "/patch_signed_7zip.apk");
    加载补丁的结果
    在tinker包下SampleResultService类中处理
    多Flavor打包

    有的时候我们希望通过flavor方式打包,在sample中提供了简单的用法事例:
    1.通过flavor编译,这个时候我们可以看到bakApk路径是一个按照flavor名称区分的目录;
    2.将编译目录路径填写到sample中tinkerBuildFlavorDirectory,其他的几个字段不需要填写,这里会自动根据路径拼接;

    ext {
        tinkerBuildFlavorDirectory = "${bakPath}/app-1014-13-35-12"
    }
    

    3.运行tinkerPatchAllFlavorDebug或者tinkerPatchAllFlavorRelease即可得到所有flavor的补丁包。

    • 关于同一版本多次打补丁问题
      Tinker支持对同一基准版本做多次补丁修复,在生成补丁时,oldApk依然是已经发布出去的那个版本。即补丁版本二的oldApk不能是补丁版本一,它应该依然是用户手机上已经安装的基准版本。
      为避免重复下载补丁包,补丁包也应有‘版本号’
      调用接口获取此时客户端版本对应的补丁包信息:
      补丁包版本号 (每次在后台上传补丁包时版本号自动递增最佳)

    相关文章

      网友评论

        本文标题:【Android】热修复之Tinker的集成与使用

        本文链接:https://www.haomeiwen.com/subject/olwxtftx.html