博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
react-native-update@4.0版本 具体热更新的机制
阅读量:6529 次
发布时间:2019-06-24

本文共 3369 字,大约阅读时间需要 11 分钟。

热更新原理

  • react-native 的程序实际上是原生的模块+JS和图片资源模块,热更新,就是更新其中的js和图片资源。

  • 安卓程序把它名字命名为zip解压后可以清楚的看到其中的bundle文件和资源文件

热更新的方法

热更新又分为全量更新和增量更新。

  • 全量更新是直接去服务器抓取你上传的ppk文件,下载下来,直接覆盖本地的ppk文件。

  • 增量更新是使用了bsdiff算法,用来比对两者bundle之间的区别,然后只修改不一样的地方。

启动程序的时候,会发一个请求给服务器,询问我需不需要更新

URL: http://update.reactnative.cn/api/checkUpdate/${key}

抓包也好,看源码也好,结论就是使用的是这个请求带上自己热更新json的key值,用来匹配你的app

{    "upToDate": true,    "ok": 1}

这个是服务器返回给我的值,如果是已经是最新的版本了,就会返回upToDate给我。

{    "expired": true,    "downloadUrl":'xxx',    "ok": 1}

如果是需要硬版本更新了,就会返回一个expired的给我,顺便给我一个downloadUrl(随便写的,具体可能不是这个名字,懒的再去删版本看了)的参数,当然这个参数是我在他家官网配置的,就是我新版本的下载地址。

这个时候,如果是需要热更新了,根据当前版本react-native-update@4.xxx的大量数据试验情况来看,返回格式无非就两种,虽然源码里有第三种

{    "update": true,    "hash": "FppJ-yU8-_bvYJe5Sg5_opUp_eFH",    "name": "0.2.1",    "description": "test",    "metaInfo": "0.2.1",    "updateUrl": "http://update-packages.reactnative.cn/FppJ-yU8-_bvYJe5Sg5_opUp_eFH?e=1483510148&token=made75kGFhOozkiRfa7LK_E1xG1pLOnhW8fhbnev:t2YXoxZZXQImvvyHH1hdrnNNRmQ=",    "pdiffUrl": "http://update-packages.reactnative.cn/lpKbEZnU6_T-mvwZGfzIQby489Bm-FppJ-yU8-_bvYJe5Sg5_opUp_eFH.pdiff?e=1483510148&token=made75kGFhOozkiRfa7LK_E1xG1pLOnhW8fhbnev:YBI4sdIEr30wa1DHV4xnMUlI1bU=",    "ok": 1}

update为true代表我需要热更新,其中有个参数叫updateUrl,这个参数提供的地址就是全量更新的地址,会把我整个bundle都下载下来。

还有一个参数叫pdiffUrl,这个就是增量更新,我会去下载一个pdiff文件,然后你检测会发现,在安卓情况下,你的cpu已经跑起来了,后台程序数据涨起来了,但是流量没动,因为走的是内部计算,测试了一下发现在不同的手机上表现也不一样。
酷派A8930:120S
ViVioX7:90S
小米5:75S。
iphone全系手机1S-5S之间。(目测不是一个人写的代码,或者是安卓读写的线程出了某些问题,仅仅是猜测)
以上时间都是单单是计算时间,因为下载增量更新那几十K也就1S的事情。

关于服务器是否返回pdiffUrl的情况我还是不能推算出官方的原理,因为同样的一个包,有的时候它会返回pdiffUrl,有的时候却只有updateUrl,不过好在不管什么情况下,都有updateUrl,那么我们就可以利用这个点,把不必要的等待给改掉。

比如我流量很多,我不想让我的安卓机器等待100S,又不想后台静默更新,那就直接改源码,好在源码找的很快,修改更是容易。

export async function downloadUpdate(options) {  if (!options.update) {    return;  }  if (options.diffUrl) {    await HotUpdate.downloadPatchFromPpk({      updateUrl: options.diffUrl,      hashName: options.hash,      originHashName: currentVersion,    });  } else if (options.pdiffUrl) {    await HotUpdate.downloadPatchFromPackage({      updateUrl: options.pdiffUrl,      hashName: options.hash,    });  } else {    await HotUpdate.downloadUpdate({      updateUrl: options.updateUrl,      hashName: options.hash,    });      }  return options.hash;}

这个就是它判断是否走增量更新的代码,其中diffUrl我从来没见到过,所以不动逻辑,所以很简单,把增量和全量调换个顺序就OK了

export async function downloadUpdate(options) {  if (!options.update) {    return;  }  if (options.diffUrl) {    await HotUpdate.downloadPatchFromPpk({      updateUrl: options.diffUrl,      hashName: options.hash,      originHashName: currentVersion,    });  } else if (options.updateUrl) {    await HotUpdate.downloadUpdate({      updateUrl: options.updateUrl,      hashName: options.hash,    });  } else {    await HotUpdate.downloadPatchFromPackage({      updateUrl: options.pdiffUrl,      hashName: options.hash,    });  }  return options.hash;}

搞定,亲测后发现,安卓在即使服务器给了我pdiffUrl的情况下,我依然也会去选择全量更新,恩,也就费个3M流量,但是大家都是无线网,所以20S以内,这个热更新肯定就好了,就不需要等待那么久了。

问题

  • 我发现这个index.js文件里没有区分Ios和安卓,所以如果我想让ios走原来的逻辑还需要判断一下,所以后续会测试下好不好用。

  • 用上了bsdiff算法后,切记切记,你的下载地址的ipa包也好,apk包也好,一定一定要和update.reactnative.cn上的包保持完全一致。否则一旦第一次走的是增量更新,那么恭喜你,无限重启。

    为什么会出现这样的问题,我的猜测是:

(update.cn上的包是7号,给用户下载地址上的包是8号,8号的程序内容比7号仅仅是多了几个文案修改。这个时候,我推送一个热更新上去,名字叫10号。那么它的计算方式本来是10号减去7号的 = 3,然后拿着这个3去加7 = 10,更新成功。但是你手里的包却是8,他还是拿10-7=3,3+8 却=11!=10.boom爆炸。11!=10,无限热更新。却永远都对不上。所以无限重启)括号内容仅仅是猜测,没有和官方沟通。

转载地址:http://cdxbo.baihongyu.com/

你可能感兴趣的文章
TD的访问地址
查看>>
一张图看懂normal,static,sealed,abstract 的 区别
查看>>
Task的使用
查看>>
s:iterator巧妙控制跳出循环
查看>>
Serv-U 的升级及数据备份和迁移【转】
查看>>
webstorm无法显示左边文件夹目录的解决方法
查看>>
数字校园-云资源平台 2014.10.26-人人通共享空间
查看>>
软件project--谈项目开发
查看>>
在Android中创建文件
查看>>
爬虫基础
查看>>
JS组件系列——再推荐一款好用的bootstrap-select组件,亲测还不错
查看>>
getopt--parse command line options
查看>>
闭包和OC的block的本质
查看>>
MySQL出现Waiting for table metadata lock的场景浅析
查看>>
C# 语言历史版本特性(C# 1.0到C# 7.1汇总更新)
查看>>
什么是数据埋点?
查看>>
git回滚
查看>>
vue2.0 引用qrcode.js实现获取改变二维码的样式
查看>>
Python 判断闰年,判断日期是当前年的第几天
查看>>
脏读,幻读,不可重复读解释和例子
查看>>