ICode9

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

关于RN的热更新

2020-02-04 12:06:51  阅读:638  来源: 互联网

标签:moduleName RCTBridge RCTRootView 更新 initialProperties 关于 RN


写点关于RN的热更新和RN版本升级后的强制更新。以及优化白屏问题

在APPDelegate中加载RN,一般的加载方式是:
RCTRootView *rootView= [[RCTRootView alloc] initWithBundleURL:jsCodeLocation moduleName:@"authen_native" initialProperties:nil launchOptions:nil];

1
2
3
4
- (instancetype)initWithBundleURL:(NSURL *)bundleURL
moduleName:(NSString *)moduleName
initialProperties:(NSDictionary *)initialProperties
launchOptions:(NSDictionary *)launchOptions;

但在调试中发现两个现象:
1.重复进入react-native页面、退出react-native页面的操作,RCTBridge对象会被重复创建、销毁。有时候RCTBridge对象未能及时创建还会crash
2.在原生页面和react-native页面相互跳转是RCTBridge也会被重复创建,造成很大的内存开销

阅读RCTRootView.h发现一些细节:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

* - Convenience initializer -
* A bridge will be created internally.
* This initializer is intended to be used when the app has a single RCTRootView,
* otherwise create an `RCTBridge` and pass it in via `initWithBridge:moduleName:`
* to all the instances.
*/
- (instancetype)initWithBundleURL:(NSURL *)bundleURL
moduleName:(NSString *)moduleName
initialProperties:(NSDictionary *)initialProperties
launchOptions:(NSDictionary *)launchOptions;

* - Designated initializer -
*/
- (instancetype)initWithBridge:(RCTBridge *)bridge
moduleName:(NSString *)moduleName
initialProperties:(NSDictionary *)initialProperties NS_DESIGNATED_INITIALIZER;

initWithBundleURL与initWithBridge的区别

对于项目中只有一个RCTRootView的时候建议initWithBundleURL的方法,这个方法内部创建了一个RCTBridge.

而有多个RCTRootView的情况,建议initWithBridge的方法.开发者直接创建RCTBridge,多个RCTRootView可共用一个RCTBridge。

项目中使用多个RCTRootView,推荐使用以下方法initWithBridge初始化:

1
2
3
4
5
6
 _bridge = [[RCTBridge alloc] initWithBundleURL:[SDRrectFileOption SetFileWithOption:self.luanchOption]
moduleProvider:nil
launchOptions:self.luanchOption];
RCTRootView = [[RCTRootView alloc] initWithBridge:_bridge
moduleName:@"authen_native"
initialProperties:nil];

在SDRrectFileOption中返回的是jsbundle的地址。在这个文件中可以使用NSFileManager来把jsbundle缓存到本地。但是如果是新版本的RN比如0.57要替换老版本的比如0.54的APP覆盖更新的话,记得要对比版本号,然后把缓存里面的jsbundle清除掉再返回新的jsbundle地址。不然会导致crash。

RN的热更新

在APPdelegate的didFinishLaunchingWithOptions方法中来判断是否需要Update。在Update方法中如果需要强制更新的话就就把RCTBridge调用reload方法进行热更新—和初始化使用的是同一个bridge。

1
2
3
4
5
6
7
8
- (void)checkUpdate {
patchClass *patch = [patchClass sharedInstance];
[patch checkUpdate];
patch.IS_COERCIVE = ^(NSURL *newPath) {
//是强制更新的话,就把RCTBridge调用reload方法进行热更新
[_bridge reload];
};
}

在patchClass中使用的是单例,在这个里面通过接口判断是否需要热更还是强制更新,是只更新jsbundle还是整包更新,下载文件,把下载的压缩文件解压缩,如果缓存里面有文件先删除旧的jsbundle再保存,

大专栏  关于RN的热更新ink" title="解决白屏问题">

标签:moduleName,RCTBridge,RCTRootView,更新,initialProperties,关于,RN
来源: https://www.cnblogs.com/lijianming180/p/12258852.html

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

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

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

ICode9版权所有