主要参考自:React Native通讯原理:http://www.jianshu.com/p/17d6f6c57a5c
1.通讯框架图
2.Native调用JS
Native调用JS流程分析:
- MessageQueue把Native调用的方法放到JavaScriptCore中
- JS Module把可以调用的方法放到MessageQueue的一个对列中
- Native从JavaScriptCore中拿到JS的调用入口,并把Module Name、Method Name、Parameters传过去
- 执行JS Module的方法
个人结合源码分析理解:
CatalystInstanceImpl包含了JavaScriptModuleRegistry,后者包含了JS模块在JAVA中对应的接口,例如index.android.js中有这么一段
import {
AppRegistry,StyleSheet,Text,View
} from 'react-native';
在 CatalystInstanceImpl实例化的时候, JavaScriptModuleRegistry中就已经被放入了相关接口的class原型(点击我看看如何被存放的)AppRegistry这个模块在JAVA中有对应的JAVA接口package com.facebook.react.uimanager; import com.facebook.react.bridge.JavaScriptModule; import com.facebook.react.bridge.WritableMap; /** * 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); }
那么getJSModule是干什么的呢,其实他是生成JS在JAVA中的接口的动态代理,我们知道,动态代理是实现了接口的方法的,而在每个方法其实是调用
JavaScriptModuleInvocationHandler中的invoke方式,传入接口的方法名和参数,之所以通过动态代理,我们的目的就是把接口的方式和参数传到JS那边,另外这个动态代理
也以便于JAVA端对象。从这里我们可以看到Cataly的含义是催化剂,催化什么呢,现在看来,就是催化我们的JS中JAVA的接口转化为实例。
JAVAScriptModuleInvocationHandler有一个Cataly实例,invoke其实是调用了Cataly实例的callFunction,而callFunction里面是一个native方法
原文链接:https://www.f2er.com/react/305448.htmlprivate native void callJSCallback(ExecutorToken executorToken,int callbackID,NativeArray arguments);现在于是我们就把JS在JAVA端的接口中的方法名字和参数传递给了C++端处理了。现在再看看CatalyInstance这个,他实际上桥接了我们的C++端和JAVA端,催化了JS在JAVA端的接口产生实例(动态代理),是通信的一个关键类现在我们通过JNI来到了libreactnativejnifb.so里面,他里面有个方法叫callJSCallback,在流程上看我们应该是去执行JSCExecutor(从名字上看意思是执行再C++端的一个JS执行者,他拿到参数后会告诉JavaScriptCore(JS引擎),JS引擎有个方法在JS BUNDEL生成的时会在JS全局变量里产生一个MESSAGEQUEUE,MESSAGEQUEUE里面有三个方法会在加载JS的时候映射为三个C++对象存下来,其中一个就是callFunctionReturnFlushedQueue,我们通过JavaScriptCore结合这个callFunctionReturnFlushedQueue在C++中的对象调用到JS,于是我们来到了JS端,例如(AppRegistry只是一个例子,实际还有很多模块)在
AppRegistry.js里面,BatchedBridge.registerCallableModule( 'AppRegistry',AppRegistry );通过这样,把本模块注入到MessageQUUE中的一个MAP对象中,而MessageQueue中的方式JSValueRef result = JSObjectCallAsFunction(m_context,m_obj,thisObj,nArgs,args,&exn);const BatchedBridge = new MessageQueue( () => global.__fbBatchedBridgeConfig,serializeNativeParams );__callFunction(module: string,method: string,args: any) { ... const moduleMethods = this._callableModules[module]; ... const result = moduleMethods[method].apply(moduleMethods,args); Systrace.endEvent(); return result; }callFunctionReturnFlushedQueue中接收的参数执行callback,而找到相应的模块中的函数调用JS的APPly方式执行这个函数
就这样执行到了JS方法,