接上篇。从ReactInstanceManager的createReactContext函数开始分析。
ReactInstanceManager.java
/**
* @return instance of {@link ReactContext} configured a {@link CatalystInstance} set
*/
private ReactApplicationContext createReactContext(
JavaScriptExecutor jsExecutor,
JSBundleLoader jsBundleLoader) {
NativeModuleRegistry.Builder nativeRegistryBuilder = new NativeModuleRegistry.Builder(); //注册(暴露给js的)native模块
JavaScriptModulesConfig.Builder jsModulesBuilder = new JavaScriptModulesConfig.Builder(); //注册(暴露给native的)js模块
ReactApplicationContext reactContext = new ReactApplicationContext(mApplicationContext);
if (mUseDeveloperSupport) {
reactContext.setNativeModuleCallExceptionHandler(mDevSupportManager); //设置调试manager
}
CoreModulesPackage coreModulesPackage =
new
CoreModulesPackage(
this,
mBackBtnHandler
)
;
processPackage(coreModulesPackage, reactContext, nativeRegistryBuilder, jsModulesBuilder); //配置核心包
//这个处理函数下面有分析
for (ReactPackage reactPackage : mPackages) { //mPackage-->new MainPackage
processPackage(reactPackage, reactContext, nativeRegistryBuilder, jsModulesBuilder); //配置main包
}
CatalystInstance.Builder catalystInstanceBuilder = new CatalystInstance.Builder() //调度类
.setCatalystQueueConfigurationSpec(CatalystQueueConfigurationSpec.createDefault())
.setJSExecutor(jsExecutor)
.setRegistry(nativeRegistryBuilder.build())
.setJSModulesConfig(jsModulesBuilder.build())
.setJSBundleLoader(jsBundleLoader)
.setNativeModuleCallExceptionHandler(mDevSupportManager);
CatalystInstance catalystInstance = catalystInstanceBuilder.build(); //这里其实就打通了java调用js代码 js调java的通道
if (mBridgeIdleDebugListener != null) { //其他不大重要的初始化过程
catalystInstance.addBridgeIdleDebugListener(mBridgeIdleDebugListener);
}
reactContext.initializeWithInstance(catalystInstance);
catalystInstance.initialize();
mDevSupportManager.onNewReactContextCreated(reactContext);
moveReactContextToCurrentLifecycleState(reactContext); //其他不大重要的初始化过程
return reactContext;
}
private voidprocessPackage( //处理函数
ReactPackage reactPackage,
ReactApplicationContext reactContext,
NativeModuleRegistry.Builder nativeRegistryBuilder,
JavaScriptModulesConfig.Builder jsModulesBuilder) {
for (NativeModule nativeModule :reactPackage.createNativeModules(reactContext)) {
nativeRegistryBuilder.add(nativeModule); //保存native包 可getModule的时候取出
}
for (Class<? extends JavaScriptModule> jsModuleClass : reactPackage.createJSModules()) {
jsModulesBuilder.add(jsModuleClass); //保存js包 可getModule的时候取出
}
}
看下core包里是些什么东西。
///coreModulesPackage.java
@Override
public
List<NativeModule>
createNativeModules
( //core包的native模块
ReactApplicationContext catalystApplicationContext) {
return
Arrays.<NativeModule>
asList
(
new
AnimationsDebugModule( //调试动画?
catalystApplicationContext
,
mReactInstanceManager
.getDevSupportManager().getDevSettings())
,
new
AndroidInfoModule()
, //??
new
DeviceEventManagerModule(catalystApplicationContext
,
mHardwareBackBtnHandler
)
, //硬件back键?
new
ExceptionsManagerModule(
mReactInstanceManager
.getDevSupportManager())
, //exception
new
Timing(catalystApplicationContext)
, //硬件刷新?
new
SourceCodeModule( //??
mReactInstanceManager
.getSourceUrl()
,
mReactInstanceManager
.getDevSupportManager().getSourceMapUrl())
,
new
UIManagerModule( //负责ui的manager
catalystApplicationContext
,
mReactInstanceManager
.createAllViewManagers(catalystApplicationContext))
,
new
DebugComponentOwnershipModule(catalystApplicationContext))
; //??
}
@Override
public
List<Class<?
extends
JavaScriptModule>>
createJSModules
() { //core包的js模块
return
Arrays.
asList
(
DeviceEventManagerModule.RCTDeviceEventEmitter.
class,
JSTimersExecution.
class, //js timer?
RCTEventEmitter.
class, //js分发touch的emitter?
AppRegistry.
class, //具体干啥?
ReactNative.
class, //??
DebugComponentOwnershipModule.RCTDebugComponentOwnership.
class
)
; //调试器
}
看下MainReactPackage包
@Override
public
List<NativeModule>
createNativeModules
(ReactApplicationContext reactContext) {
return
Arrays.<NativeModule>
asList
(
new
AsyncStorageModule(reactContext)
, //?
new
FrescoModule(reactContext)
, //fresco
new
NetworkingModule(reactContext)
, //network
new
ToastModule(reactContext))
; //toast(咦 一个toast有那么重要么
}
@Override
public
List<ViewManager>
createViewManagers
(ReactApplicationContext reactContext) { //暴露给js的android控件
return
Arrays.<ViewManager>
asList
(
new
ReactDrawerLayoutManager()
,
new
ReactHorizontalScrollViewManager()
,
new
ReactImageManager()
,
new
ReactProgressBarViewManager()
,
new
ReactRawTextManager()
,
new
ReactScrollViewManager()
,
new
ReactSwitchManager()
,
new
ReactTextInputManager()
,
new
ReactTextViewManager()
,
new
ReactToolbarManager()
,
new
ReactViewManager()
,
new
ReactViewPagerManager()
,
new
ReactVirtualTextViewManager())
;
}
上面提到经过process后其实已经打通了java和js交互的通道,下面跟踪上篇文章中的一个java调用js代码的
runApplication例子来进一步分析具体是怎么实现通信的。
catalystInstance.getJSModule(AppRegistry.class).runApplication(jsAppModuleName, appParams);
public <T extends JavaScriptModule> T getJSModule(Class<T> jsInterface) { //获取一个js模块
return Assertions.assertNotNull(mJSModuleRegistry).getJavaScriptModule(jsInterface);
}
public <T extends JavaScriptModule> TgetJavaScriptModule(Class<T> moduleInterface) {
return (T) Assertions.assertNotNull(
mModuleInstances.get(moduleInterface),///mModuleInstances(hashMap类型 在下面的构造函数中会看到
"JS module " + moduleInterface.getSimpleName() + " hasn't been registered!");
} //从这里看出getJSModule函数其实是取出了一个存在mModuleInstance这个map中的某个类 其实就是在上面process后存储的
JavaScriptModuleRegistry.java
public JavaScriptModuleRegistry(
CatalystInstance instance,
JavaScriptModulesConfig config) {
mModuleInstances = new HashMap<>();
for (JavaScriptModuleRegistration registration : config.getModuleDefinitions()) {
Class<? extends JavaScriptModule> moduleInterface = registration.getModuleInterface(); //由process过程存储
JavaScriptModule interfaceProxy =(JavaScriptModule) Proxy.newProxyInstance(
moduleInterface.getClassLoader(),
new Class[]{moduleInterface},
new JavaScriptModuleInvocationHandler(instance,registration)); //内部类 //这里动态生成的handler是关键-->js require只有一个实体(这样可以确保比如AppRegistry.class实体和js AppRegistry.js一一对应关系
mModuleInstances.put(moduleInterface, interfaceProxy); //根据每个接口生成一个对象 并存入map
}
}
JavaScriptModuleInvocationHandler
@Override
public @Nullable Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String tracingName = mModuleRegistration.getTracingName(method); //mModuleRegistration就是上面的registration
mCatalystInstance.callFunction(
mModuleRegistration.getModuleId(), //根据moduleId和methodId找到正确的函数(这里是AppRegistry.runApplication)
//并调用-->下面会看到
mModuleRegistration.getMethodId(method),
Arguments.fromJavaArgs(args),
tracingName);
return null;
}
CatalystInstance.java
/* package */ void callFunction(
final int moduleId,
final int methodId,
final NativeArray arguments,
final String tracingName) {
incrementPendingJSCalls();
mCatalystQueueConfiguration.getJSQueueThread().runOnQueue(
new Runnable() {
@Override
public void run() {
mCatalystQueueConfiguration.getJSQueueThread().assertIsOnThread();
Assertions.assertNotNull(mBridge).callFunction(moduleId, methodId, arguments);
//调用mBridge的callFunction
}
});
}
ReactBridge.java //看到名字就知道是一个桥梁
private native void initialize(
JavaScriptExecutor jsExecutor
,
ReactCallback callback,
MessageQueueThread nativeModulesQueueThread)
;
public native void loadScriptFromAssets(AssetManager assetManager, String assetName);
public native void loadScriptFromNetworkCached(String sourceURL, @Nullable String tempFileName);
public native void callFunction(int moduleId, int methodId, NativeArray arguments); //native代码 java-->native了
public native void invokeCallback(int callbackID, NativeArray arguments);
public native void setGlobalVariable(String propertyName, String jsonEncodedArgument);
public native boolean supportsProfiling();
public native void startProfiler(String title);
public native void stopProfiler(String title, String filename);
}
///后面就转入native调用js代码的过程了 由下面的文章进行分析。
ok~ 这篇文章就先到这里了~
这篇文章分析了ReactContext初始化的过程,可以看到reactContext初始化的时候将java包括native的一些重要
模块注册到了catalyst里,搭起了java js通信的基础。
并跟踪了其中一个runApplication的例子,看到java将moduleId,methodId,args传到了native层,至于native层如何
调用js代码,这篇文章并没有分析。