前言

facebook的react-native给我们带来了用js写出原生应用的同时,也使得使用RN编写的代码的在线升级变得可能,终于可以不通过应用市场来进行升级,极大的提升了app修bug和赋予新功能的能力。----使用h5的方式也可以做到,但是rn的用户体验可要远远超过h5啊。

一般使用RN编写的app的线上使用方式,是将react-native bundle命令打出bundle文件和assets文件夹,直接内置到app中,app在viewcontroller或者activity中直接加载app内部的bundle文件,比如下图。

当修改了代码或者图片的时候,只要app使用新的bundle文件和assets文件夹,就完成了一次在线升级。

本文主要基于以上思路,讲解增量升级的解决方案。

何为增量?

一个完整的RN-app程序通常包含以下几个部分:

  1. native代码部分-objc或者java
  2. js代码部分-rn代码、依赖的第三方库、业务代码等
  3. 图片资源部分

native代码别想了,没法在线升级,要是能大家就都不使用应用市场ota升级了。

能进行在线升级的是js代码部分和图片资源部分,具体到代码就是bundle文件和assets文件夹。

因为在线升级是要走网络的,我们要想办法将网络消耗降到最低,所以要使用增量升级的方式。

针对js代码部分(即bundle文件)的增量指的是,代码的改动有多少,增量patch的补丁就有多少,那些没有改动的代码部分是不在补丁的范围内的。

针对图片部分(即assets)的增量指的是,升级补丁包中只包含新增的图片和有改动的图片。

那么在app端,下载升级补丁包,只需要和现有的版本进行合并,就能计算出最新版本的全量包。

总结下流程:()中为例子

首先,计算增量包:新版本(v10) - 旧版本(v1到v9) = 增量包 (会有9个包,v1~v10.zip,v2~v10.zip,,,,,v9-v10.zip)

然后,app根据自己的当前版本(比如V6),下载对应的增量包(V6-V10.zip)。

最后,app中通过 旧版本(v6) + 增量包(v6~v10.zip) = 新版本(v10) ,计算出了新版本的全量包。

增量算法

assets增量算法,比较简单,就是比对,可以很容易的比较出新增的文件,和不同的文件(使用md5)。

bundle文件的增量算法,确实比较复杂,刚开始没有什么头绪,后来在leader的指引下,很幸运的找到了google写的一个开源的库,可以对大字符串进行diff和patch,并且支持java、objc、js等等语言,完全的满足了我们的需求。

只用到2个接口,具体请参考github上的文档

  1. 生成增量包时候:patch_make(text1, text2) => patches
  2. app生成全量包时候:patch_apply(patches, text1) => [text2, results]

google开源库地址:https://github.com/bystep15/google-diff-match-patch

codepush

微软的codepush也做了类似的事情,不过由于以下原因,我们团队没敢使用其作为解决方案。

  1. 其增量升级仅仅是针对图片资源的
  2. 其升级服务器端程序并不开源
  3. 其升级服务器在美国,国内访问很慢且不稳定

不过,codepush客户端的源码和文档也给我们提供了很多思路,在此感谢codepush团队。

codepush地址:http://microsoft.github.io/code-push/

bundle要求的app最小版本

本文中一般用min-v或者appMinV表示。

因为js代码是依赖于native代码的,所以,jsbundle对app的版本有要求,所以有这个概念。

试想,如果bundle依赖了一个native的一个新的接口,这个接口在v3版本的app中才发布,如果v2版本的app升级了这个bundle,那么必然会报错,严重的可能会导致app的崩溃。

系统结构设计与各模块职责

bundle仓库设计

存储全量bundle和生成增量patch

node patch 命令

在bundle目录下放入一个符合要求【参考目录结构说明】的新版本目录,比如0.3.0,然后执行以下命令。

命令:node patch 版本号 , 示例:node patch 0.3.0

-d参数: node patch 版本号 -d ,如果加入-d参数,会先删除patch目录下的对应版本目录,然后进行patch生成

然后在patch目录中就会生成0.3.0的增量包,同时patch目录下的update.json文件也会重新生成.

node update.json 命令

在patch目录下重新生成update.json文件

目录结构说明

  1. bundle 存放全量bundle和全量assets的目录,里面的文件基本上是使用react-native bundle命令生成的
  2. 0.1.0

  3. 0.2.0
  4. android
  5. 略,同ios
  6. ios
  7. config.json 此版本的配置信息,包含要求app的最低版本等,手动配置
  8. index.jsbundle 全量jsbundle文件,使用react-native bundle命令生成
  9. assets 全量图片目录,使用react-native bundle命令生成
  10. 0.3.0
  11. patch 存放增量补丁的目录,里面文件都是命令生成的,无需手动维护
  12. 0.1.0
  13. 第一版本无文件
  14. 0.2.0
  15. android
  16. 略,同ios
  17. ios
  18. 0.1.0-0.2.0.zip 增量包.zip
  19. 0.3.0
  20. android
  21. 略,同ios
  22. ios
  23. 0.1.0-0.3.0.zip 增量包.zip
  24. 0.2.0-0.3.0.zip 增量包.zip
  25. update.json 所有的升级包信息
  26. src 存放打包用的源码
  27. lib 存放打包用依赖的第三方的源码
  28. patch.js patch命令入口
  29. update.json.js update.json命令入口

config.json示例

  1. {
  2. "v": "0.3.0", //版本
  3. "min-v": "4.0.0", //此版本要求的最小app版本
  4. "date": "2016-01-01", //打包日期
  5. "des": [
  6. "修复xxbug", "添加xx功能"
  7. ]
  8. }

update.json示例

  1. [
  2. {
  3. "v": "0.1.0",
  4. "min-v": "4.0.0",
  5. "date": "2016-01-01",
  6. "des": [
  7. "修复xxbug",
  8. "添加xx功能"
  9. ],
  10. "iosBundleMd5": "11f82563f8fd3f22dccb80ad2297f7bc",
  11. "androidBundleMd5": "11f82563f8fd3f22dccb80ad2297f7bc"
  12. },
  13. {
  14. "v": "0.2.0",
  15. "min-v": "4.0.0",
  16. "date": "2016-01-01",
  17. "des": [
  18. "修复xxbug",
  19. "添加xx功能"
  20. ],
  21. "iosBundleMd5": "3ca2824b008132cee515c0ea29938ff2",
  22. "androidBundleMd5": "3ca2824b008132cee515c0ea29938ff2"
  23. },
  24. {
  25. "v": "0.3.0",
  26. "min-v": "4.0.0",
  27. "date": "2016-01-01",
  28. "des": [
  29. "修复xxbug",
  30. "添加xx功能"
  31. ],
  32. "iosBundleMd5": "dbb81d2383112abb50eb19970c486acd",
  33. "androidBundleMd5": "dbb81d2383112abb50eb19970c486acd"
  34. }
  35. ]

升级服务器设计

接口patch/query

例如:http://localhost:3000/patch/query?bundleV=0.2.0&appV=4.0.0&platform=ios

此接口会有以下4个场景的使用情况,每个场景返回的json示例已经提供在后面文档中。

输入参数

  1. ```
  2. bundleV : app中的bundle版本
  3. appV : app版本
  4. platform : app的平台
  5. ```

返回json各项说明

  1. status : 本次请求后台是否发生了错误
  2. msg : 给用户看的中文提示信息,静默升级时候没什么用
  3. latestBundleV : 当前的最新bundle版本
  4. latestAppMinV : 最新bundle要求的app最低版本
  5. canUpdate : 能否升级,boolean
  6. canUpdateBundleV : 能升级的bundle版本
  7. canUpdateAppMinV : 能升级的bundle要求的app最低版本
  8. patchUrl : 补丁包相对地址
  9. platform : 平台:ios or android

场景1

能升级,且能升级到最新版

  1. {
  2. status: 'success',
  3. msg: '可以升级,bundle最新版为0.3.0',
  4. latestBundleV: '0.3.0',
  5. latestAppMinV: '4.0.0',
  6. canUpdate: true,
  7. canUpdateBundleV: '0.3.0',
  8. canUpdateAppMinV: '4.0.0',
  9. patchUrl: 'patch/0.3.0/ios/0.2.0-0.3.0.zip',
  10. platform: 'ios'
  11. }

场景2

无需升级,已经是最新版本

  1. {
  2. status: 'success',
  3. msg: '无需升级,已经是最新版本',
  4. canUpdate: false,
  5. platform: 'ios'
  6. }

场景3

能升级,能升级到当前appMinV的最新bundle版本,但不是最新的bundle,想升最新bundle,必须先升app

  1. {
  2. status: 'success',
  3. msg: '可以升级,但app版本3.0.0太低,只能升到bundleV0.2.0,bundleV最新为0.3.0',
  4. latestBundleV: '0.3.0',
  5. latestAppMinV: '4.0.0',
  6. canUpdate: true,
  7. canUpdateBundleV: '0.2.0',
  8. canUpdateAppMinV: '3.0.0',
  9. patchUrl: 'patch/0.2.0/ios/0.1.0-0.2.0.zip',
  10. platform: 'ios'
  11. }

场景4

不能升级,已经是当前appMinV的最新bundle,但不是最新的bundle,想升最新bundle,必须先升app

  1. {
  2. status: 'success',
  3. msg: '不能升级,当前已经是app3.0.0的最新bundle了,但不是最新bundle0.3.0,想升级bundle到最新,请先升级app',
  4. latestBundleV: '0.3.0',
  5. latestAppMinV: '4.0.0',
  6. canUpdate: false,
  7. platform: 'ios'
  8. }

native客户端设计

客户端的主要工作就是发请求到升级服务器询问是否能升级,然后根据返回的信息,下载升级包,解压升级包,安装升级包。

过程中要保证下载的文件是正确的(md5校验),要保证补丁安装之后的全量bundle文件是正确的(md5校验)。

整个过程用户无感知。

此部分详细设计后边会补充。

原文地址

react native 增量升级方案(转)的更多相关文章

  1. 1000 千米高空俯瞰 React Native

    一.历史:React Native 从开始到现在 React Native 的定位是通过 React 构建原生 App: A framework for building native apps wi ...

  2. 【独家】React Native 版本升级指南

    前言 React Native 作为一款跨端框架,有一个最让人头疼的问题,那就是版本更新.尤其是遇到大版本更新,JavaScript.iOS 和 Android 三端的配置构建文件都有非常大的变动,有 ...

  3. Hybrid App 和 React Native 开发那点事

    简介:Hybrid App(混合模式移动应用)开发是指介于Web-app.Native-App这两者之间的一种开发模式,兼具「Native App 良好用户交互体验的优势」和「Web App 跨平台开 ...

  4. React Native库版本升级与降级

    迄今为止React Native获得了超过48K的star,最新版本0.44,已经趋于稳定.(官网地址:https://github.com/facebook/react-native).随着Reac ...

  5. React Native 在 Airbnb(译文)

    在Android,iOS,Web和跨平台框架的横向对比中,React Native本身是一个相对较新且快速开发移动的平台.两年后,我们可以肯定地说React Native在很多方面都是革命性的.这是移 ...

  6. React Native拆包及热更新方案 · Solartisan

    作者:solart 版权声明:本文图文为博主原创,转载请注明出处. 随着 React Native 的不断发展完善,越来越多的公司选择使用 React Native 替代 iOS/Android 进行 ...

  7. 移动端跨平台方案对比:React Native、weex、Flutter

    跨平台一直是老生常谈的话题,cordova.ionic.react-native.weex.kotlin-native.flutter等跨平台框架百花齐放,颇有一股推倒原生开发者的势头. 为什么我们需 ...

  8. 最火移动端跨平台方案盘点:React Native、weex、Flutter

    1.前言 跨平台一直是老生常谈的话题,cordova.ionic.react-native.weex.kotlin-native.flutter等跨平台框架的百花齐放,颇有一股推倒原生开发者的势头. ...

  9. React Native升级目标SDK

    React Native升级目标SDK 打开在 android/app/的build.gradle 找到 android { } 区块 改变以下属性 compileSdkVersion 26 buil ...

随机推荐

  1. java重写和重载

    方法的重载: 在一个类中的两个或两个以上的方法,他们方法名相同但是参数列表不同,这种方式称为方法的重载,方法的重载是实现多态性的方式之一. 参数列表不同指的是参数的个数不同或相同的个数但顺序不同或者类 ...

  2. 芝麻HTTP:TensorFlow基础入门

    本篇内容基于 Python3 TensorFlow 1.4 版本. 本节内容 本节通过最简单的示例 -- 平面拟合来说明 TensorFlow 的基本用法. 构造数据 TensorFlow 的引入方式 ...

  3. AJAX的简洁写法

    // ajax操作 $('#btn').on('click',function(){ var url = "{:url('confirm')}"; var actual_money ...

  4. Java中使用UDP实现简单的聊天功能

    通过DatagramSocket类来实现.此类表示用来发送和接收数据报包的套接字. 发送端代码如下: import java.io.IOException; import java.net.*; im ...

  5. SAXParser解析xml文件

    对于xml的解析,这里学习并演示使用SAXParser进行解析的样例. 使用此种方法无法解析"gb2312"编码的xml文件,因此,此处xml文件编码设置为"UTF-8& ...

  6. 第三篇:一个Spark推荐系统引擎的实现

    前言 经过2节对MovieLens数据集的学习,想必读者对MovieLens数据集认识的不错了:同时也顺带回顾了些Spark编程技巧,Python数据分析技巧. 本节将是让人兴奋的一节,它将实现一个基 ...

  7. 【BZOJ2330】【SDOI2012】糖果(差分约束,SPFA)

    [BZOJ2330][SDOI2012]糖果 题面 题目描述 幼儿园里有N个小朋友,lxhgww老师现在想要给这些小朋友们分配糖果,要求每个小朋友都要分到糖果.但是小朋友们也有嫉妒心,总是会提出一些要 ...

  8. [Luogu4175][CTSC2008]网络管理Network

    又是权限题qwq 一句话题意:带修改树上路径第k大 sol 数据结构?还是再见吧.学一手合格的整体二分,只有思维强大,才能见题拆题. 如果你做过整体二分的动态区间第k大就会发现这是一样的题. 无非是区 ...

  9. [BZOJ2684][CEOI2004]锯木厂选址

    BZOJ权限题! Description 从山顶上到山底下沿着一条直线种植了n棵老树.当地的政府决定把他们砍下来.为了不浪费任何一棵木材,树被砍倒后要运送到锯木厂. 木材只能按照一个方向运输:朝山下运 ...

  10. 通过银行卡号识别归属银行,php方式

    这个例子不是很全,要做到齐全必须使用数据库字典来索引,而且数据量庞大,建议生产使用时限制几大行就行,直接不支持其他小行.此案例抛砖引玉 /** * 银行卡信息识别相关类 * 把bin号转化为长整形,再 ...