ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

安卓开发SDK全局热更新方案

2022-05-21 09:03:30  阅读:256  来源: 互联网

标签:安卓 更新 Tinker 差分 tinker 全局 SDK 加载


一、背景
App热更新
目前市面上成熟的商业热更新方案不少,有腾讯Bugly的Tinker封装,有阿里云的Sophix,也有游戏垂直行业的卓盟乐变。这些成熟方案,都有一个适用范围,即对App、对游戏整包进行热更新。前两者是和包名绑定在一起的,所以只适用于App热更新;而卓盟乐变则专注于游戏行业,可支持多渠道包热更新。其实最好的还是Sophix,可惜没有开源,虽有公开原理,但是公开资料里也透露了探索与开发周期长达9个月。

在社区,比较流行的热更新有Tinker、QZone、AndFix(HotFix)、Sophix、Robust、Dexposed、Nuwa、Amigo,同商业热更新方案一样,也是适用于App整包热更新。在这些方案里,影响力最大的是微信的Tinker方案,13048个Star,拥有完善的文档,整个框架注重高可用性,最重要的是官方持续维护,在2018年12月,merge7次。相比之下,其他有在Github上开源的框架,star数都是7000以下,上次更新时间都在1年前,甚至2年前。

SDK热更新
SDK热更新,这是一个极少被关注的问题,Google、百度上相关的文章一篇都没有。我们首先进行思考,SDK热更新同App热更新有什么不同?,SDK热更新要做什么?

SDK热更新同App热更新有什么不同?
•App热更新,输入的是一个基准包和一个新版包,输出的是差分包(或补丁),将这个差分包(或补丁)下载到客户端,客户端加载后生效。•SDK热更新,输入的是一个基准SDK和一个新版SDK,输出的也是差分包(或补丁),不同的是,SDK会被集成到不同的游戏包中,这个游戏包也会被分成各式各样的渠道包,我们要将这个差分包(或补丁)下载到所有游戏、所有渠道包,并加载生效。

SDK热更新要做什么?
1. 对SDK的代码、资源进行标识,我们要进行热更新的对象,就是这些代码、资源。
比如,我们可以进行这样标识:所有在com.divin.包名之下的java类,所有assets/divin/文件夹之下的Assets文件,所有以divin_开头的Res文件,所有/res/values/文件,所有以divin_开头的so文件。

2. 在热更新的整个流程,对上述代码、资源进行特别操作。
包括build(计算差分)、patch(合并差分)、load(加载差分)。

十分感谢微信Tinker的开源,对外开放了完整的热更新过程,站在伟人肩上,下面的SDK热更新,都是基于Tinker开源库进行的修改。

热更新重点
1. dex热更新,即Java代码热更新。
阿里系(AndFix,Hotfix)走的底层替换方案,好处在于实时生效,腾讯系(Tinker)走的是类加载方案,好处在于高兼容性。阿里百川系(Sophix)就有点机智了,两种方案都有使用,还进行了一定的升级,优先走底层替换方案,底层替换方案走不下去了就走类加载方案。

AndFix(HotFix)的底层替换方案已过时,Sophix的无视底层具体结构的底层替换方案较新。感兴趣的同学可以深入了解下,追寻极致的代码热替换[1]。

Tinker的类加载方案,需要重启应用后让Classloader去加载新类。因为Android上无法对一个类进行卸载,不重启,则无法加载新类。

2. 资源文件热更新。
这里也是有两个流派,一个流派是参考Instant Run通过addAssetPath加载新的资源包到AssetsManager,然后再替换Resource中的AssetsManager;一个流派是构造新的R文件资源地址以0x66开头的资源包,再通过addAssetPath加载新的资源包到AssetsManager,因为新的R文件资源地址以0x66开头,新的Java代码里,也引用0x66开头的资源,这样就可以新旧资源不干扰且都能生效。

Tinker属于第一个流派[2],Sophix属于第二个流派[3]。

非常遗憾的是,在我们基于Tinker实现SDK资源更新(即指定资源更新)时,只知道第一个流派,并不知道第二个流派(那篇文章没细读,印象不深)。所以后文中所提到的SDK资源更新(指定资源更新),其实是自己摸索出来的,可以理解成流派二的拼多多版,实现了资源新增、更改,但暂未支持R文件直接引用。

3. so文件热更新。
说到这里,是真感谢这世界上有数组这玩意。so文件的热更新,也是把补丁so库的路径插入到nativeLibraryDirectories数组的最前面。

二、Tinker
开源
Tinker已开源,Tencent/tinker[4],同时有详细的使用Wiki,Tinker使用Wiki[5]。

热更新过程
Tinker的整个热更新过程,可以理解成四个步骤。

1. Tinker集成
集成Tinker分两大块,一块是Application改造,一块是定制化功能。第一块较为简单,使用Annotation Processor在编译时生成新Application;第二块非常复杂。

2. build(计算差分)
build有两种模式,一种是供Android Studio开发使用的Gradle模式,一种是使用Java实现的命令行模式。二者最底层,其实都是使用的tinker-patch-lib,一个用Java实现的核心库。

3. patch(合并差分)
4. load(加载差分)
源码结构
Tinker的源码分为这么几大块:

1. tinker-sample-android
顾名思义,这是一个demo,庞大!庞大!庞大!从未见过一个第三方SDK,暴露了如此多的api,可以定制如此多的功能!难怪Sophix在其官方文档中对热更新方案做横向对比时,把自己描述为“傻瓜式接入”,把Amigo描述为“一般”,却把Tinker描述为“复杂”。其实微信官方也有描述,Tinker为了实现“高可用”的目标,在接入成本上做了妥协。热补丁并不简单,在使用之前请务必先仔细阅读XXXX。总的来说,感谢腾讯baba。

demo里,示例了:

①如何控制热更新的请求过滤、合并过程、加载过程、合并后的后续处理、升级热更新模块本身的代码。

②如何改造Application。

③Gradle集成模式的42个参考配置。 42个参考配置!42个参考配置!42个参考配置!

这里让大家放心的是,复杂的是Tinker的定制化开发,而不是给到cp的SDK。我们可以对外隐藏这些定制化开发的细节。

2. tinker-build
这是热更新过程中build步骤的源码,有三个子模块,tinker-patch-lilb是核心代码,tinker-patch-cli是命令行模式的源码,tinker-patch-gradle-plugin是Gradle模式的源码。

3. tinker-android
这是热更新过程中patch和load步骤的源码,随Apk、游戏运行在客户端。也有Application改造时用到的Annotation Processor库的源码。

4. tinker-commons
tinker-build所用到的基础库。

5. third-party
tinker-build所用到的第三方库。
————————————————
版权声明:本文为CSDN博主「安卓进化论」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/d29h1jqy3akvx/article/details/88984620

标签:安卓,更新,Tinker,差分,tinker,全局,SDK,加载
来源: https://www.cnblogs.com/i1lii1il/p/16294373.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有