React Native for Android 原理分析与实践:实现原理,深入剖析

本文深入剖析React Native在Android平台的启动流程和渲染原理,从ReactInstanceManager的创建、ReactContext的生成、JS Bundle加载到ReactRootView的绑定,揭示RN页面如何启动并渲染。通过理解关键角色如JavascriptModuleRegistry和CatalystInstance,以及JS执行和三端通信,帮助开发者深化对React Native的理解。
摘要由CSDN通过智能技术生成
  • JavascriptModuleRegistry:JavascriptModuleRegistry是JS Module映射表,NativeModuleRegistry是Java Module映射表

以上便是整套框架中关键的角色,值得一提的是,当页面真正渲染出来以后,它实际上还是Native代码,React Native的作用就是把JavaScript代码映射成Native代码以及实现两端 的通信,所以我们在React Native基础框架搭建的过程中,指导思路之一就是弱化Native与RN的边界与区别,让业务开发组感受不到两者的区别,从而简化开发流程。

好,有了对React Native框架的整体理解,我们来继续分析一个RN页面是如何启动并渲染出来的,这也是我们关心的主要问题。后续的基础框架的搭建、JS Bundle分包加载、渲染性能优化 等都会围绕着着一块做文章。

二 启动流程

我们知道RN的页面也是依托Activity,React Native框架里有一个ReactActivity,它就是我们RN页面的容器。ReactActivity里有个ReactRootView,正如它的名字那样,它就是 ReactActivity的root View,最终渲染出来的view都会添加到这个ReactRootView上。ReactRootView调用自己的startReactApplication()方法启动了整个RN页面,在启动的过程 中先去创建页面上下文ReactContext,然后再去加载、执行并将JavaScript映射成Native Widget,最终一个RN页面就显示在了用户面前。

整个RN页面的启动流程图如下所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这个流程看起来有点长,但实际上重要的东西并不多,我们当前只需要重点关注四个问题:

  1. ReactInstanceManager是如何被创建的,它在创建的时候都初始化了哪些对象?🤔
  2. RN页面上下文ReactContext在创建的过程中都做了什么,都初始化了哪些对象?🤔
  3. JS Bundle是如何被加载的?🤔
  4. JS入口页面是如何被渲染出来的?🤔

2.1 创建ReactInstanceManager

我们先来看第一个问题,我们都知道要使用RN页面,就需要先初始化一个ReactNativeHost,它是一个抽象类,ReactInstanceManager就是在这个类里被创建的,如下所示:

public abstract class ReactNativeHost {
protected ReactInstanceManager createReactInstanceManager() {

ReactInstanceManagerBuilder builder = ReactInstanceManager.builder()
//应用上下文
.setApplication(mApplication)
//JSMainModuleP相当于应用首页的js Bundle,可以传递url从服务器拉取js Bundle
//当然这个只在dev模式下可以使用
.setJSMainModulePath(getJSMainModuleName())
//是否开启dev模式
.setUseDeveloperSupport(getUseDeveloperSupport())
//红盒的回调
.setRedBoxHandler(getRedBoxHandler())
//JS执行器
.setJavaScriptExecutorFactory(getJavaScriptExecutorFactory())
//自定义UI实现机制,这个我们一般用不到
.setUIImplementationProvider(getUIImplementationProvider())
.setInitialLifecycleState(LifecycleState.BEFORE_CREATE);

//添加我们外面设置的Package
for (ReactPackage reactPackage : getPackages()) {
builder.addPackage(reactPackage);
}

//获取js Bundle的加载路径
String jsBundleFile = getJSBundleFile();
if (jsBundleFile != null) {
builder.setJSBundleFile(jsBundleFile);
} else {
builder.setBundleAssetName(Assertions.assertNotNull(getBundleAssetName()));
}
return builder.build();
}
}

2.2 创建ReactContext

我们再来看第二个问题,ReactContext创建流程序列图如下所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

可以发现,最终创建ReactContext是createReactContext()方法,我们来看看它的实现。

public class ReactInstanceManager {

private ReactApplicationContext createReactContext(
JavaScriptExecutor jsExecutor,
JSBundleLoader jsBundleLoader) {
Log.d(ReactConstants.TAG, “ReactInstanceManager.createReactContext()”);
ReactMarker.logMarker(CREATE_REACT_CONTEXT_START);
//ReactApplicationContext是ReactContext的包装类。
final ReactApplicationContext reactContext = new ReactApplicationContext(mApplicationContext);

//debug模式里开启异常处理器,就是我们开发中见到的调试工具(红色错误框等)
if (mUseDeveloperSupport) {
reactContext.setNativeModuleCallExceptionHandler(mDevSupportManager);
}

//创建JavaModule注册表
NativeModuleRegistry nativeModuleRegistry = processPackages(reactContext, mPackages, false);

NativeModuleCallExceptio

  • 26
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值