react-native之热更新

什么是热更新

简单说就是不需要去应用市场重新下载,直接打开app就会下载更新的内容然后进入app,类似于经常玩游戏,游戏里需要更新,然后就有个进度条在读取。总结就是可以不通过应用市场来进行升级,极大的提升了app修bug和赋予新功能的能力

RN热更新的原理是什么

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

  • native代码部分

  • js代码部分-rn代码、依赖的第三方库、业务代码等

  • 图片资源部分

native代码发生了变动

如果你的项目的native代码发生了变动,对不起,热更新不能满足你的需求,你只能硬更新,让用户重新下载新的来覆盖旧的app。截止的当前日期,RN的版本还只是0.32,距离1.0还很遥远。所以经常会有需要用到的功能,而RN原生没有封装,所以只能亲自来写,当然,如果我们有一个完整的无线团队,那么是极好的,直接去把无线团队里的类库中筛选个一些可能会用到的功能,先提前封装进来,尽量的减少热更新的次数。

图片资源或者是js发生变动

而如果我们是想修改图片资源或者是js的代码部分,好的,可以使用热更新,那么既然是热更新,我就置想去修改变动的内容,计算方法:新版本(V3.1) - 旧版本(v3.0) = 增量包

好的,以上都是理论原理内容,由于项目期只有2个人在做RN前端方面的开发,所以没有足够的时间去开发公司内部的热更新。所以使用了第三方的组件react-native-pushy

如何使用react-native-pushy

注册一个pushy账号

pushy

配置Bundle URL(iOS)

在工程target的Build Phases->Link Binary with Libraries中加入libz.tbd、libbz2.1.0.tbd

在你的AppDelegate.m文件中增加如下代码:

// ... 其它代码

#import "RCTHotUpdate.h"

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
#if DEBUG
  // 原来的jsCodeLocation
  jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle?platform=ios&dev=true"];
#else
  jsCodeLocation=[RCTHotUpdate bundleURL];
#endif
  // ... 其它代码
}

配置Bundle URL(Android)

0.29及以后版本:在你的MainApplication中增加如下代码:

// ... 其它代码

import cn.reactnative.modules.update.UpdateContext;
public class MainApplication extends Application implements ReactApplication {

  private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
    @Override
    protected String getJSBundleFile() {
        return UpdateContext.getBundleUrl(MainApplication.this);
    }
    // ... 其它代码
  }
}

0.28及以前版本:在你的MainActivity中增加如下代码:

// ... 其它代码

import cn.reactnative.modules.update.UpdateContext;

public class MainActivity extends ReactActivity {

    @Override
    protected String getJSBundleFile() {
        return UpdateContext.getBundleUrl(this);
    }
    // ... 其它代码
}

添加热更新功能

页面需要引用react-native-update模块

import {
  isFirstTime,isRolledBack,packageVersion,currentVersion,checkUpdate,downloadUpdate,switchVersion,switchVersionLater,markSuccess,} from 'react-native-update';

通常情况下,热更新的判断需要在app启动上来就要进行判断,那么大多数都会写在index.android.js中

componentWillMount(){
    //去除debug时候的警告,测试的时候建议打开,hotloading的时候可以关掉
    // console.disableYellowBox = true;
    // 2s 后如果还没有响应 则提示并取消
    let freshedFlag = false;
    let timeout = setTimeout(() => {
         timeout && clearTimeout(timeout);
         
         if (freshedFlag) return;

         freshedFlag = true;

         console.log('超时');
         
         //做些什么,比如setState让页面跳过

    },REQ_TIMEOUT);
    
    //防止反触发,就是更新完了回滚
    markSuccess();
    
    //异步函数checkUpdate可以检查当前版本是否需要更新
    
    checkUpdate(appKey).then(info => {
      // freshedFlag 为 true 则说明超时
      console.log('timeout'+freshedFlag);
      if (freshedFlag) {
          return;
      } else {
          freshedFlag = true;
      }
      //包过期,需要下载最新版的应用(非热更新)
      if (info.expired) {
          //进度条隐藏,新版本弹窗,提供下载地址
          this.setState({
              progressState:false,showDialog:true,downloadUrl:info.downloadUrl
          })
      }
      //当前版本是最新版本,无需热更新 
      else if (info.upToDate) {
          this.setState({
            progressState:false,progressNum: 100,welcome:false,update:false
          })
      } else {
          //需要热更新了
          this.doUpdate(info)
      }

    }).catch(err => {
      this.setState({
        progressState:false,})
    });
  }
  //热更新函数
  doUpdate = info => {
    
    //做点什么,让你的UI显示出来,提供个假性的进度条什么的
    
    downloadUpdate(info).then(hash => {
        //下载完版本返回一个hash字符串,是当前笨笨的唯一标示,然后切换版本
      switchVersion(hash);
    }).catch(err => {
      this.setState({
        progressState:false,})
    });
  };

就理论而言,热更新操作到此结束,但是实际使用过程中,5000个用户大概会有100个丢掉的可能性。不是特别的准,也存在少量用户回滚版本的行为。听说公司其他部门的团队做的app用的是codePush,后期也可以多研究一下。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


react 中的高阶组件主要是对于 hooks 之前的类组件来说的,如果组件之中有复用的代码,需要重新创建一个父类,父类中存储公共代码,返回子类,同时把公用属性...
我们上一节了解了组件的更新机制,但是只是停留在表层上,例如我们的 setState 函数式同步执行的,我们的事件处理直接绑定在了 dom 元素上,这些都跟 re...
我们上一节了解了 react 的虚拟 dom 的格式,如何把虚拟 dom 转为真实 dom 进行挂载。其实函数是组件和类组件也是在这个基础上包裹了一层,一个是调...
react 本身提供了克隆组件的方法,但是平时开发中可能很少使用,可能是不了解。我公司的项目就没有使用,但是在很多三方库中都有使用。本小节我们来学习下如果使用该...
mobx 是一个简单可扩展的状态管理库,中文官网链接。小编在接触 react 就一直使用 mobx 库,上手简单不复杂。
我们在平常的开发中不可避免的会有很多列表渲染逻辑,在 pc 端可以使用分页进行渲染数限制,在移动端可以使用下拉加载更多。但是对于大量的列表渲染,特别像有实时数据...
本小节开始前,我们先答复下一个同学的问题。上一小节发布后,有小伙伴后台来信问到:‘小编你只讲了类组件中怎么使用 ref,那在函数式组件中怎么使用呢?’。确实我们...
上一小节我们了解了固定高度的滚动列表实现,因为是固定高度所以容器总高度和每个元素的 size、offset 很容易得到,这种场景也适合我们常见的大部分场景,例如...
上一小节我们处理了 setState 的批量更新机制,但是我们有两个遗漏点,一个是源码中的 setState 可以传入函数,同时 setState 可以传入第二...
我们知道 react 进行页面渲染或者刷新的时候,会从根节点到子节点全部执行一遍,即使子组件中没有状态的改变,也会执行。这就造成了性能不必要的浪费。之前我们了解...
在平时工作中的某些场景下,你可能想在整个组件树中传递数据,但却不想手动地通过 props 属性在每一层传递属性,contextAPI 应用而生。
楼主最近入职新单位了,恰好新单位使用的技术栈是 react,因为之前一直进行的是 vue2/vue3 和小程序开发,对于这些技术栈实现机制也有一些了解,最少面试...
我们上一节了了解了函数式组件和类组件的处理方式,本质就是处理基于 babel 处理后的 type 类型,最后还是要处理虚拟 dom。本小节我们学习下组件的更新机...
前面几节我们学习了解了 react 的渲染机制和生命周期,本节我们正式进入基本面试必考的核心地带 -- diff 算法,了解如何优化和复用 dom 操作的,还有...
我们在之前已经学习过 react 生命周期,但是在 16 版本中 will 类的生命周期进行了废除,虽然依然可以用,但是需要加上 UNSAFE 开头,表示是不安...
上一小节我们学习了 react 中类组件的优化方式,对于 hooks 为主流的函数式编程,react 也提供了优化方式 memo 方法,本小节我们来了解下它的用...
开源不易,感谢你的支持,❤ star me if you like concent ^_^
hel-micro,模块联邦sdk化,免构建、热更新、工具链无关的微模块方案 ,欢迎关注与了解
本文主题围绕concent的setup和react的五把钩子来展开,既然提到了setup就离不开composition api这个关键词,准确的说setup是由...
ReactsetState的执行是异步还是同步官方文档是这么说的setState()doesnotalwaysimmediatelyupdatethecomponent.Itmaybatchordefertheupdateuntillater.Thismakesreadingthis.staterightaftercallingsetState()apotentialpitfall.Instead,usecom