欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android热修复(一):Tinker的使用(一)命令行接入

程序员文章站 2024-03-20 19:16:52
...

介绍

    Tinker是微信官方的Android热补丁解决方案,它支持动态下发代码、So库以及资源,让应用能够在不需要重新安装的情况下实现更新。当然,你也可以使用Tinker来更新你的插件。
    它主要包括以下几个部分:
        gradle编译插件(主要是为了帮助我们在Android Studio直接生成patch文件): tinker-patch-gradle-plugin
        核心sdk库(tinker为用户提供的所有的api): tinker-android-lib
        非gradle编译用户的命令行版本(主要是为了使用命令行来生成patch文件): tinker-patch-cli.jar
    现在有许多热修复方案,比如说我上次介绍的阿里的AndFix,美团的Robust,QQ空间的超级补丁方案,那么我们为什么还要去学习Tinker呢?Tinker的优势在哪里呢?

Android热修复(一):Tinker的使用(一)命令行接入
总的来说:
1、AndFix作为native解决方案,首先面临的是稳定性与兼容性问题,更重要的是它无法实现类替换,它是需要大量额外的开发成本的;
2、Robust兼容性与成功率较高,但是它与AndFix一样,无法新增变量与类只能用做的bugFix方案;
3、Qzone方案可以做到发布产品功能,但是它主要问题是插桩带来Dalvik的性能问题,以及为了解决Art下内存地址问题而导致补丁包急速增大的。

Tinker的集成

添加依赖

    //自定义注解库  生成application时使用
    provided 'com.tencent.tinker:tinker-android-anno:1.7.7'
    //tinker核心库
    compile 'com.tencent.tinker:tinker-android-lib:1.7.7'
    //支持分包,不需要分包可以不导入
    compile 'com.android.support:multidex:1.0.1'

Tinker初始化

    //判断是否安装(初始化)tinker
    private static boolean isInstalled = false;
    private static ApplicationLike mAppLike;
    ......
        //初始化tinker
    public static void installTinker(ApplicationLike applicationLike){
        mAppLike = applicationLike;
        if(isInstalled){
            return;
        }else {
            TinkerInstaller.install(applicationLike);
            isInstalled = true;
        }
    }
    Tinker不能直接调用它的初始化方法,而是需要在ApplicationLike中去使用。先创建一个ApplicationLike的类,然后在onBaseContextAttached()方法中去调用它的初始化方法。
@DefaultLifeCycle(application = ".MyApplication", flags = ShareConstants.TINKER_ENABLE_ALL,
        loadVerifyFlag = false)
public class CustomTinkerLike extends ApplicationLike {
    public CustomTinkerLike(Application application, int tinkerFlags, boolean tinkerLoadVerifyFlag,
                            long applicationStartElapsedTime, long applicationStartMillisTime,
                            Intent tinkerResultIntent) {
        super(application, tinkerFlags, tinkerLoadVerifyFlag, applicationStartElapsedTime,
                applicationStartMillisTime, tinkerResultIntent);
    }

    @Override
    public void onBaseContextAttached(Context base) {
        super.onBaseContextAttached(base);

        //使用multidex,使应用支持分包
        MultiDex.install(base);

        //初始化tinker
        TinkerPatchManager.installTinker(this);
    }
}
    然后rebuild一下项目,然后就会生成MyApplication.

Android热修复(一):Tinker的使用(一)命令行接入
可以在manifest来使用这个application

Patch文件的加载

    //加载patch
    public static void loadPatch(String path){
        if(Tinker.isTinkerInstalled()){
            TinkerInstaller.onReceiveUpgradePatch(getApplicationContext(),path);
        }
    }

    //通过ApplicationLink获取Context
    private static Context getApplicationContext(){
        if(mAppLike != null){
            return mAppLike.getApplication().getApplicationContext();
        }

        return null;
    }

Tinker的使用

    首先和上篇AndFix的使用一样,我们首先构建出存放patch文件的路径,即我们要加载的patch文件的路径。
    //patch文件后缀名
    private static final String FILE_END = ".apk";
    //patch文件的路径
    private String mPatchDir;
    ......
    mPatchDir = getExternalCacheDir().getAbsolutePath() + "/tpatch/";
    Log.v("xq_msg", "path: " + mPatchDir);
    //创建文件夹
    File file = new File(mPatchDir);
    if (file == null || !file.exists()) {
        file.mkdir();
    }
    ......
    //构造patch文件名
    private String getPatchName() {
        return mPatchDir.concat("xq_sq").concat(FILE_END);
    }
    然后写一个按钮来调用我们加载patch文件的方法
    //加载patch
    public void loadPatch(View view) {
        TinkerPatchManager.loadPatch(getPatchName());
    }
    再在我们的Manifest文件中添加
    //用来判断这个patch文件是否能加载到我们的手机当中,只有当patch文件的id和我们手机中的apk的id一致才能加载
     <meta-data
            android:name="TINKER_ID"
            android:value="tinker_id_1"/>
    接着打出老的apk(签名版),先保存一份(我们后面还需要用它来生成patch文件),再安装到手机中。我们再修改一下代码(例如我们修改一下布局,增加一个按钮,然后打包,打出新的apk)

生成patch文件(使用命令行)

    首先我们需要先下载命令行工具(链接在文章末尾),它主要包括下图圈出来的几个部分,其他是我们生成命令行需要的一些文件

Android热修复(一):Tinker的使用(一)命令行接入

    然后我们需要去修改tinker_config.xml文件的2个地方,如下图所示,一个是loader,我们需要改成我们的application的全路径,一个是最下面的签名文件的一个配置

Android热修复(一):Tinker的使用(一)命令行接入

     然后我们就可以使用我们的命令来生成我们的patch文件了。
    java -jar tinker-patch-cli.jar -old old.apk -new new.apk -config tinker_config.xml -out output_path
    我们对应修改一些来执行我们的命令
java -jar tinker-patch-cli-1.7.7.jar -old tinker_old.apk -new tinker_new.apk -config tinker_config.xml -out output/

Android热修复(一):Tinker的使用(一)命令行接入

    然后我们可以在我们的output文件夹中去找到我们的生成的patche文件

Android热修复(一):Tinker的使用(一)命令行接入

    我们需要的就是这签名了patch文件,然后我们使用adb命令来将这个文件push到我们代码中对应的目录下,然后点击loadPatch按钮,应用自动重启,再次打开我们会发现,我们新增的按钮已经出现了。这个使用命令行来接入Tinker与我们上次讲到的AndFix的使用是没有太大的区别。但是我们在实际项目中都是使用配置gradle文件来使用我们的Tinker的,这个我们在后续的文章中也会讲到具体的是怎么使用配置gradle文件使用Tinker的。

源码下载地址和命令行工具的下载地址

源码及下载工具