tinker接入

Easter79
• 阅读 559

对于热修复无非就是两大类,一类是tencent代表的classloader模式的,另一类是阿里系代表的底层方面替换。

下面以本人的经验介绍下微信的tinker接入:

    命令行接入方式; gradle接入方式

1. 核心库引入,在你应用的app模块下build.gradle文件加入

//tinker hotfix    //可选,用于生成application类//    compileOnly("com.tencent.tinker:tinker-android-anno:${TINKER_VERSION}")    //tinker's main Android lib    implementation "com.tencent.tinker:tinker-android-lib:${TINKER_VERSION}"如果应用开启了multiDex(一般应用都会用到),还必须加入如下配置

defaultConfig {   ...   ...    multiDexEnabled true    //必须打入第一个dex包的java类    multiDexKeepProguard file("tinker_multidexkeep.pro") }当然其实上述采用的是proguard方式加入到Main dex中,当然也可以采用multiDexKeepFile方式(一行一个类形式)主要目的就是确保tinker的包中类分到第一个dex中,具体可以参考:https://juejin.im/entry/5893e54f128fe100654763a0https://www.kancloud.cn/alex_wsc/artist/481985、https://blog.csdn.net/zhangbuzhangbu/article/details/52770939

其实关于分包模式的问题,可以参考我的一片博文: https://www.cnblogs.com/linghu-java/p/10983671.htmlhttps://www.kancloud.cn/alex_wsc/android_plugin/481528

2、一般应用的application都有很多特殊的初始化和配置的内容,所以这里不打算使用注解生成application的方式,而是自己加入tinker的内容。   明文写出Application的构造函数,在里面调用super类TinkerApplication的构造函数

  public class WishApplication extends TinkerApplication {

    public WishApplication(){        super(//tinkerFlags, which types is supported dex only, library only, all support              ShareConstants.TINKER_ENABLE_ALL,              // This is passed as a string so the shell application does not              // have a binary dependency on your ApplicationLifeCycle class.              "com.yunzhiyuan100.wish.SimpleApplicationLike");

    }

}如果本来extends MultiApplictiaon的话就要换成 extends TinkerApplication了,然后重写attachBaseContext()方法,在该方法里加入MultiDex的内容。如下protected void attachBaseContext(Context base) {

    super.attachBaseContext(base);    MultiDex.install(this);}然后就是你原来Application的代码逻辑的内容,可以不用变动3. 然后自定义Application中初始化函数用到ApplicationLike类参数实例,可以直接按照tinker给的代码拷贝

 1 public class SimpleApplicationLike extends ApplicationLike {
 2 
 3     public SimpleApplicationLike(Application application, int tinkerFlags, boolean tinkerLoadVerifyFlag,
 4                                  long applicationStartElapsedTime, long applicationStartMillisTime, Intent tinkerResultIntent) {
 5         super(application, tinkerFlags, tinkerLoadVerifyFlag, applicationStartElapsedTime, applicationStartMillisTime, tinkerResultIntent);
 6     }
 7 
 8     @Override
 9     public void onBaseContextAttached(Context base) {
10         super.onBaseContextAttached(base);
11 
12     }
13     @Override
14     public void onCreate() {
15         super.onCreate();
16         TinkerInstaller.install(this);
17     }
18 
19     @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
20     public void registerActivityLifecycleCallbacks(Application.ActivityLifecycleCallbacks callback) {
21         getApplication().registerActivityLifecycleCallbacks(callback);
22     }
23 
24 }

 4. proguard改变

1 #your dex.loader pattern here
2 -keep class com.tencent.tinker.loader.**
3 #注意 AndroidManifest.xml中的applicaion
4 -keep class com.yunzhiyuan100.wish.WishApplication
5 
6 # ***************** Tinker patch包
7 # 打替换apk包的时候需要
8 -applymapping mapping.txt

然后就可以打包了,打old.apk的时候自动生成mapping.txt, 第二次打new.apk包的时候为了保持混淆的一致性,要使用第一混淆的时候的mapping文件,

-applymapping mapping.txt

5.  AndroidManifest修改,application标签下面加入

1 <meta-data
2     android:name="TINKER_ID"
3     android:value="20190604" />

6.下载Thinker的项目 

  tinker提供了patch生成的工具,源码见:tinker-patch-cli,打成一个jar就可以使用,并且提供了命令行相关的参数以及文件。

       tinker的项目地址: https://github.com/Tencent/tinker

       然后通过android studio打开整个项目

  (1). 在控制台输入:./gradlew buildTinkerSdk    (window上gradlew buildTinkerSdk)

      在指定路径看到生成的文件之后,将刚才生成的old.apk和new.apk拷贝进去。

       (2). 修改tinker_config.xml

    loader修改成自己的application

<issue id="dex">
        <!--only can be 'raw' or 'jar'. for raw, we would keep its original format-->
        <!--for jar, we would repack dexes with zip format.-->
        <!--if you want to support below 14, you must use jar-->
        <!--or you want to save rom or check quicker, you can use raw mode also-->
        <dexMode value="jar"/>

        <!--what dexes in apk are expected to deal with tinkerPatch-->
        <!--it support * or ? pattern.-->
        <pattern value="classes*.dex"/>
        <pattern value="assets/secondary-dex-?.jar"/>

        <!--Warning, it is very very important, loader classes can't change with patch.-->
        <!--thus, they will be removed from patch dexes.-->
        <!--you must put the following class into main dex.-->
        <!--Simply, you should add your own application {@code tinker.sample.android.SampleApplication}-->
        <!--own tinkerLoader {@code SampleTinkerLoader}, and the classes you use in them-->
        <loader value="com.tencent.tinker.loader.*"/>
        <loader value="com.yunzhiyuan100.wish.WishApplication"/>
    </issue>

另外,如果是正式包,需要修改签名配置为你项目的签名,还需要把签名文件yunzhiyuan.jks放到buildSDK的目录build下面

  <!--sign, if you want to sign the apk, and if you want to use 7zip, you must fill in the following data-->
    <issue id="sign">
        <!--the signature file path, in window use \, in linux use /, and the default path is the running location-->
        <path value="yunzhiyuan.jks"/>
        <!--storepass-->
        <storepass value="bgsb1709@hzyzy"/>
        <!--keypass-->
        <keypass value="bgsb1709@hzyzy"/>
        <!--alias-->
        <alias value="wish"/>
    </issue>

(3)最后就可以执行patch命令打出差异包了

  命令行如下: 

  java -jar tinker-patch-cli-1.9.13.jar -old old.apk -new new.apk -config tinker_config.xml -out output

注意tinker-patch-cli这个jar包的名字要和buildSdk/build/目录下的该jar包版本名称一致

把打出来的差异包adb push 到sdcard目录下: adb push patch_sign.apk   /sdcard/

然后在MainActivity中加载差异包,通过加入一个按钮的点击调用下面的loadFix()函数

1 public void loadFix(){
2   TinkerInstaller.onReceiveUpgradePatch(getApplicationContext(),
3   Environment.getExternalStorageDirectory().getAbsolutePath() + "/patch_signed.apk");
4 }

这里调用loadFix()之后,应用会被关闭,再次打开,测试得到想要的修改结果。

大功告成了

参考:

    https://blog.csdn.net/YANGDAHUAN/article/details/81021801

    https://blog.csdn.net/lmj623565791/article/details/54882693

    https://github.com/Tencent/tinker

    https://github.com/Tencent/tinker/wiki/Tinker-%E6%8E%A5%E5%85%A5%E6%8C%87%E5%8D%97

    https://blog.csdn.net/cjw8990/article/details/79117880

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Easter79 Easter79
2年前
SpringBoot自定义序列化的使用方式
场景及需求:项目接入了SpringBoot开发,现在需求是服务端接口返回的字段如果为空,那么自动转为空字符串。例如:\    {        "id":1,        "name":null    },    {        "id":2,        "name":"x
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Stella981 Stella981
2年前
SpringBoot自定义序列化的使用方式
场景及需求:项目接入了SpringBoot开发,现在需求是服务端接口返回的字段如果为空,那么自动转为空字符串。例如:\    {        "id":1,        "name":null    },    {        "id":2,        "name":"x
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这
Easter79
Easter79
Lv1
今生可爱与温柔,每一样都不能少。
文章
2.8k
粉丝
5
获赞
1.2k