加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

菜鸟学习React Native for Android 之通讯原理分析(JAVA调用JS

发布时间:2020-12-15 08:19:53 所属栏目:百科 来源:网络整理
导读:主要参考自:React Native通讯原理:http://www.jianshu.com/p/17d6f6c57a5c 1.通讯框架图 2.Native调用JS Native调用JS流程分析: MessageQueue把Native调用的方法放到JavaScriptCore中 JS Module把可以调用的方法放到MessageQueue的一个对列中 Native从Jav

主要参考自:React Native通讯原理:http://www.jianshu.com/p/17d6f6c57a5c

1.通讯框架图


2.Native调用JS

Native调用JS流程分析:

  1. MessageQueue把Native调用的方法放到JavaScriptCore中
  2. JS Module把可以调用的方法放到MessageQueue的一个对列中
  3. Native从JavaScriptCore中拿到JS的调用入口,并把Module Name、Method Name、Parameters传过去
  4. 执行JS Module的方法


个人结合源码分析理解:

CatalystInstanceImpl包含了JavaScriptModuleRegistry,后者包含了JS模块在JAVA中对应的接口,例如index.android.js中有这么一段
import {
 AppRegistry,StyleSheet,Text,View
} from 'react-native';
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);
}
CatalystInstanceImpl实例化的时候, JavaScriptModuleRegistry中就已经被放入了相关接口的class原型(点击我看看如何被存放的)

那么getJSModule是干什么的呢,其实他是生成JS在JAVA中的接口的动态代理,我们知道,动态代理是实现了接口的方法的,而在每个方法其实是调用

JavaScriptModuleInvocationHandler中的invoke方式,传入接口的方法名和参数,之所以通过动态代理,我们的目的就是把接口的方式和参数传到JS那边,另外这个动态代理

也以便于JAVA端对象。从这里我们可以看到Cataly的含义是催化剂,催化什么呢,现在看来,就是催化我们的JS中JAVA的接口转化为实例。

JAVAScriptModuleInvocationHandler有一个Cataly实例,invoke其实是调用了Cataly实例的callFunction,而callFunction里面是一个native方法

private 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中的方式
callFunctionReturnFlushedQueue中接收的参数执行callback,而找到相应的模块中的函数调用JS的APPly方式执行这个函数

就这样执行到了JS方法,
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; }

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读