<commit_before>作者: 郭孝星  
邮箱: <EMAIL>  
博客: http://blog.csdn.net/allenwells   
简书: http://www.jianshu.com/users/66a47e04215b/latest_articles  

**关于作者**

>郭孝星，非著名程序员，代码洁癖患者，爱编程，好吉他，喜烹饪，爱一切有趣的事物和人。

**关于文章**

>作者的文章会同时发布在Github、CSDN与简书上, 文章顶部也会附上文章的Github链接。如果文章中有什么疑问也欢迎发邮件与我交流, 对于交流
的问题, 请描述清楚问题并附上代码与日志, 一般都会给予回复。如果文章中有什么错误, 也欢迎斧正。如果你觉得本文章对你有所帮助, 也欢迎去
star文章, 关注文章的最新的动态。另外建议大家去Github上浏览文章，一方面文章的写作都是在Github上进行的，所以Github上的更新是最及时
的，另一方面感觉Github对Markdown的支持更好，文章的渲染也更加美观。

文章目录：https://github.com/guoxiaoxing/react-native-android-container/blob/master/README.md

>通信，指的是RN中Java与JS的通信，即JS中的JSX代码如何转化成Java层真实的View与事件的，以及JavaFile层又是如何调用JS来找出它需要的View与
事件的。

在正式介绍通信流程之前，我们先来看看整个流程中牵扯到的各个类的作用。

```
ReactInstanceManager：创建ReactContext、CatalystInstance等类，解析ReactPackage生成映射表，并且配合ReactRootView管理View的创建与生命周期等功能。
ReactContext：继承于ContextWrapper，是Rn应用的上下文，可以通过getContext()去获得。
ReactRootView：Rn应用的根视图。
ReactBridge：通信的核心类，通过JNI方式进行调用，C++层作为通信中间层。
NativeModuleRegistry：Java Module映射表。
JavascriptModuleRegistry：JS Module映射表。
CoreModulePackage：RN核心框架Package，包括Java接口与JS接口。
MainReactPackage：Rn封装的一些通用的Java组件与事件。
JSBundleLoader：用于加载JSBundle的类，根据不同的情况会创建不同的Loader。
JSBundle：JS代码包，存放JS核心逻辑。
```

在上一篇文章：[ReactNative源码篇：启动流程](https://github.com/guoxiaoxing/awesome-react-native/blob/master/doc/ReactNative源码篇/2ReactNative源码篇：启动流程.md)中，我们知道RN应用在启动的时候会创建JavaScriptModule映射表（JavaScriptModuleRegistry）与NativeModule映射表（NativeModuleRegistry），RN中Java层
与JS层的通信就是通过这两张表来完成的，我们来详细看一看。

## Java层调用JS层

**举例**

在上一篇文章：[ReactNative源码篇：启动流程](https://github.com/guoxiaoxing/awesome-react-native/blob/master/doc/ReactNative源码篇/2ReactNative源码篇：启动流程.md)中，我们在ReactInstanceManager.onAttachedToReactInstance()方法中调用APPRegistry.jS的runApplication()来
启动RN应用，这就是一个典型的Java层调用JS层的例子，我们来具体分析一下这个例子的实现方式。

1 首先定义了接口AppRegistry，该接口继承于JavaScriptModule，如下所示：

```java
/**
 * JS module interface - main entry point for launching React application for a given key.
 */
public interface AppRegistry extends JavaScriptModule {

  void runApplication(String appKey, WritableMap appParameters);
  void unmountApplicationComponentAtRootTag(int rootNodeTag);
  void startHeadlessTask(int taskId, String taskKey, WritableMap data);
}

```

2 然后在CoreModulesPackage.createJSModules()将它添加到JavaScriptModule列表中，这个列表最终会被添加到JavaScriptModuleRegistry中。

```java
class CoreModulesPackage extends LazyReactPackage implements ReactPackageLogger {
  @Override
  public List<Class<? extends JavaScriptModule>> createJSModules() {
    List<Class<? extends JavaScriptModule>> jsModules = new ArrayList<>(Arrays.asList(
        DeviceEventManagerModule.RCTDeviceEventEmitter.class,
        JSTimersExecution.class,
        RCTEventEmitter.class,<commit_msg>update react native start flow<commit_after>作者: 郭孝星  
邮箱: <EMAIL>  
博客: http://blog.csdn.net/allenwells   
简书: http://www.jianshu.com/users/66a47e04215b/latest_articles  

**关于作者**

>郭孝星，非著名程序员，代码洁癖患者，爱编程，好吉他，喜烹饪，爱一切有趣的事物和人。

**关于文章**

>作者的文章会同时发布在Github、CSDN与简书上, 文章顶部也会附上文章的Github链接。如果文章中有什么疑问也欢迎发邮件与我交流, 对于交流
的问题, 请描述清楚问题并附上代码与日志, 一般都会给予回复。如果文章中有什么错误, 也欢迎斧正。如果你觉得本文章对你有所帮助, 也欢迎去
star文章, 关注文章的最新的动态。另外建议大家去Github上浏览文章，一方面文章的写作都是在Github上进行的，所以Github上的更新是最及时
的，另一方面感觉Github对Markdown的支持更好，文章的渲染也更加美观。

文章目录：https://github.com/guoxiaoxing/react-native-android-container/blob/master/README.md

>通信，指的是RN中Java与JS的通信，即JS中的JSX代码如何转化成Java层真实的View与事件的，以及JavaFile层又是如何调用JS来找出它需要的View与
事件的。

在正式介绍通信流程之前，我们先来看看整个流程中牵扯到的各个类的作用。

```
ReactInstanceManager：创建ReactContext、CatalystInstance等类，解析ReactPackage生成映射表，并且配合ReactRootView管理View的创建与生命周期等功能。
ReactContext：继承于ContextWrapper，是Rn应用的上下文，可以通过getContext()去获得。
ReactRootView：Rn应用的根视图。
ReactBridge：通信的核心类，通过JNI方式进行调用，C++层作为通信中间层。
NativeModuleRegistry：Java Module映射表。
JavascriptModuleRegistry：JS Module映射表。
CoreModulePackage：RN核心框架Package，包括Java接口与JS接口。
MainReactPackage：Rn封装的一些通用的Java组件与事件。
JSBundleLoader：用于加载JSBundle的类，根据不同的情况会创建不同的Loader。
JSBundle：JS代码包，存放JS核心逻辑。
```

在上一篇文章[ReactNative源码篇：启动流程](https://github.com/guoxiaoxing/awesome-react-native/blob/master/doc/ReactNative源码篇/2ReactNative源码篇：启动流程.md)中，我们知道RN应用在启动的时候会创建JavaScriptModule映射表（JavaScriptModuleRegistry）与NativeModule映射表（NativeModuleRegistry），RN中Java层
与JS层的通信就是通过这两张表来完成的，我们来详细看一看。

## Java层调用JS层

**举例**

在上一篇文章[ReactNative源码篇：启动流程](https://github.com/guoxiaoxing/awesome-react-native/blob/master/doc/ReactNative源码篇/2ReactNative源码篇：启动流程.md)中，我们在ReactInstanceManager.onAttachedToReactInstance()方法中调用APPRegistry.jS的runApplication()来
启动RN应用，这就是一个典型的Java层调用JS层的例子，我们来具体分析一下这个例子的实现方式。

1 首先定义了接口AppRegistry，该接口继承于JavaScriptModule，如下所示：

```java
/**
 * JS module interface - main entry point for launching React application for a given key.
 */
public interface AppRegistry extends JavaScriptModule {

  void runApplication(String appKey, WritableMap appParameters);
  void unmountApplicationComponentAtRootTag(int rootNodeTag);
  void startHeadlessTask(int taskId, String taskKey, WritableMap data);
}

```

2 然后在CoreModulesPackage.createJSModules()将它添加到JavaScriptModule列表中，这个列表最终会被添加到JavaScriptModuleRegistry中。

```java
class CoreModulesPackage extends LazyReactPackage implements ReactPackageLogger {
  @Override
  public List<Class<? extends JavaScriptModule>> createJSModules() {
    List<Class<? extends JavaScriptModule>> jsModules = new ArrayList<>(Arrays.asList(
        DeviceEventManagerModule.RCTDeviceEventEmitter.class,
        JSTimersExecution.class,
        RCTEventEmitter.class,
{'fraction_non_alphanumeric': 0.09312721177127957, 'fraction_numerical': 0.004842615012106538, 'mean_word_length': 9.804828973843058, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 21, 'https://': 6, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '828142', 'n_tokens_mistral': 2727, 'n_tokens_neox': 3024, 'n_words': 213}