React Native是怎么在Android上跑起来的
(源码版本:0.34,新版本(0.48)基本流程是不变的,建议跟着源码看看,哪个版本的倒影响不大)
启动流程
startReactApplication(ReactInstanceManager reactInstanceManager,String moduleName,@Nullable Bundle launchOptions)
这个方法参数第一个 下一步到了 //JavaScriptExecutor 默认就是jsc,如果的debug在chrome上时候,就是v8。
//JSBundleLoader 有AssetLoader FileLoader CachedBundleFromNetworkLoader RemoteDebuggerBundleLoader 从不同的地方加载bundle
private void recreateReactContextInBackground(
JavaScriptExecutor.Factory jsExecutorFactory,JSBundleLoader jsBundleLoader) {
UiThreadUtil.assertOnUiThread();
ReactContextInitParams initParams =
new ReactContextInitParams(jsExecutorFactory,jsBundleLoader);
if (mReactContextInitAsyncTask == null) {
// No background task to create react context is currently running,create and execute one.
mReactContextInitAsyncTask = new ReactContextInitAsyncTask();
mReactContextInitAsyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,initParams);
} else {
// Background task is currently running,queue up most recent init params to recreate context
// once task completes.
mPendingReactContextInitParams = initParams;
}
}
主要的创建工作就转移到了 @Override
protected Result<ReactApplicationContext> doInBackground(ReactContextInitParams... params) {
....
return Result.of(createReactContext(jsExecutor,params[0].getJsBundleLoader()));
....
}
private ReactApplicationContext createReactContext(
JavaScriptExecutor jsExecutor,JSBundleLoader jsBundleLoader) {
...
NativeModuleRegistry.Builder nativeRegistryBuilder = new NativeModuleRegistry.Builder();//NativeModule的注册表
JavaScriptModuleRegistry.Builder jsModulesBuilder = new JavaScriptModuleRegistry.Builder();//jsModules的注册表
...打包定义的各种modules到上面的注册表...
//创建关键的CatalystInstanceImpl
CatalystInstanceImpl.Builder catalystInstanceBuilder = new CatalystInstanceImpl.Builder()
...
catalystInstance = catalystInstanceBuilder.build();
....
//扔到js线程中加载js脚本
catalystInstance.getReactQueueConfiguration().getJSQueueThread().callOnQueue(
new Callable<Void>() {
@Override
public Void call() throws Exception {
//让reactContext持有catalystInstance
reactContext.initializeWithInstance(catalystInstance);
...
catalystInstance.runJSBundle();
return null;
}
}).get();
}
在 ...
//native C++方法,用来初始化JNI相关状态然后返回mHybridData。具体在 OnLoad.cpp 的 JSCJavaScriptExecutorHolder 类中
mHybridData = initHybrid();
...
//初始化线程环境,包括和主线程绑定,JS线程,Native线程创建。
mReactQueueConfiguration = ReactQueueConfigurationImpl.create(
ReactQueueConfigurationSpec,new NativeExceptionHandler());
...
initializeBridge(
new BridgeCallback(this),//CatalystInstanceImpl内部类,用于native对java的一些回调
jsExecutor,//jsc
mReactQueueConfiguration.getJSQueueThread(),//js线程队列
mReactQueueConfiguration.getNativeModulesQueueThread(),//native线程队列
mJavaRegistry.getModuleRegistryHolder(this));//nativemodules注册表
mMainExecutorToken = getMainExecutorToken();//貌似是用于切换jsExecutor的标记,后面版本删掉了。
然后就进入到了 void CatalystInstanceImpl::initializeBridge(
jni::alias_ref<ReactCallback::javaobject> callback,// This executor is actually a factory holder.
JavaScriptExecutorHolder* jseh,jni::alias_ref<JavaMessageQueueThread::javaobject> jsQueue,jni::alias_ref<JavaMessageQueueThread::javaobject> moduleQueue,ModuleRegistryHolder* mrh) {
instance_->initializeBridge(folly::make_unique<JInstanceCallback>(callback),jseh->getExecutorFactory(),folly::make_unique<JMessageQueueThread>(jsQueue),folly::make_unique<JMessageQueueThread>(moduleQueue),mrh->getModuleRegistry());
}
然后有委托给了 void Instance::initializeBridge(
std::unique_ptr<InstanceCallback> callback,std::shared_ptr<JSExecutorFactory> jsef,std::shared_ptr<MessageQueueThread> jsQueue,std::unique_ptr<MessageQueueThread> nativeQueue,std::shared_ptr<ModuleRegistry> moduleRegistry) {
callback_ = std::move(callback);
//在js线程中包装nativeQueue和创建nativeToJsBridge_,后者在双向bridge起作用,不要仅仅看名字,内部还有一个JsToNativeBridge
jsQueue->runOnQueueSync(
[this,&jsef,moduleRegistry,jsQueue,nativeQueue=folly::makeMoveWrapper(std::move(nativeQueue))] () mutable {
nativeToJsBridge_ = folly::make_unique<NativeToJsBridge>(
jsef.get(),nativeQueue.move(),callback_);
});
CHECK(nativeToJsBridge_);
}
到这就看没了,再回到上面的 void Instance::loadScriptFromFile(const std::string& filename,const std::string& sourceURL) {
...检测文件合法性等...
loadScriptFromString(std::move(buf),sourceURL);
}
void Instance::loadScriptFromString(std::unique_ptr<const JSBigString> string,std::string sourceURL) {
callback_->incrementPendingJSCalls();//这个callback就是java层的CatalystInstanceImpl的BridgeCallback这个内部类。
...
nativeToJsBridge_->loadApplicationScript(std::move(string),std::move(sourceURL));
}
void NativeToJsBridge::loadApplicationScript(std::unique_ptr<const JSBigString> script,std::string sourceURL) {
m_mainExecutor->loadApplicationScript(std::move(script),std::move(sourceURL));
}
void JSCExecutor::loadApplicationScript(std::unique_ptr<const JSBigString> script,std::string sourceURL) throw(JSException) {
...
//使用webkit JSC去真正解释执行Javascript了!
evaluateScript(m_context,jsScript,jsSourceURL);
//绑定桥,核心是通过getGlobalObject将JS与C++通过webkit JSC bind
bindBridge();
flush();
}
void JSCExecutor::bindBridge() throw(JSException) {
...下面都是通过jsc 获取js的一下属性,方法等...
auto global = Object::getGlobalObject(m_context);
auto batchedBridgeValue = global.getProperty("__fbBatchedBridge");
...
auto batchedBridge = batchedBridgeValue.asObject();
m_callFunctionReturnFlushedQueueJS = batchedBridge.getProperty("callFunctionReturnFlushedQueue").asObject();
m_invokeCallbackAndReturnFlushedQueueJS = batchedBridge.getProperty("invokeCallbackAndReturnFlushedQueue").asObject();
//这个比较重要 获取MessageQueue.js的flushedQueue 下面就用到
m_flushedQueueJS = batchedBridge.getProperty("flushedQueue").asObject();
}
//这个下面js->native的时候还会提到
void JSCExecutor::flush() {
...真的烦,绕来绕去 m_flushedQueueJS看上面
callNativeModules(m_flushedQueueJS->callAsFunction({}));
}
void JSCExecutor::callNativeModules(Value&& value) {
...
try {
auto calls = value.toJSONString();
//class JsToNativeBridge : public react::ExecutorDelegate
m_delegate->callNativeModules(*this,std::move(calls),true);
} catch (...) {
...
}
}
void callNativeModules(
JSExecutor& executor,std::string callJSON,bool isEndOfBatch) override {
ExecutorToken token = m_nativeToJs->getTokenForExecutor(executor);
m_nativeQueue->runOnQueue([this,token,callJSON=std::move(callJSON),isEndOfBatch] {
for (auto& call : react::parseMethodCalls(callJSON)) {
//快完了 这个是ModuleRegistry.cpp 是在initializeBridge间接创建包装nativemodule的
m_registry->callNativeMethod(
token,call.moduleId,call.methodId,std::move(call.arguments),call.callId);
}
if (isEndOfBatch) {
//又见到了这个callback
m_callback->onBatchComplete();
m_callback->decrementPendingJSCalls();
}
});
}
void ModuleRegistry::callNativeMethod(ExecutorToken token,unsigned int moduleId,unsigned int methodId,folly::dynamic&& params,int callId) {
...
modules_[moduleId]->invoke(token,methodId,std::move(params));
}
看到最后一句就是要去调用 说到这里,现在只完成了 @Override
protected void onPostExecute(Result<ReactApplicationContext> result) {
....
setupReactContext(result.get());
}
private void setupReactContext(ReactApplicationContext reactContext) {
...各种listener回调,通知birdge就绪,reactContext创建完成
for (ReactRootView rootView : mAttachedRootViews) {
attachMeasuredRootViewToInstance(rootView,catalystInstance);
}
...各种listener回调,通知birdge就绪,reactContext创建完成
}
private void attachMeasuredRootViewToInstance(ReactRootView rootView,CatalystInstance catalystInstance) {
....
UIManagerModule uiManagerModule = catalystInstance.getNativeModule(UIManagerModule.class);
int rootTag = uiManagerModule.addMeasuredRootView(rootView);
rootView.setRootViewTag(rootTag);
@Nullable Bundle launchOptions = rootView.getLaunchOptions();
WritableMap initialProps = Arguments.makeNativeMap(launchOptions);
String jsAppModuleName = rootView.getJSModuleName();
WritableNativeMap appParams = new WritableNativeMap();
appParams.putDouble("rootTag",rootTag);
appParams.putMap("initialProps",initialProps);
//真正拉起react native 的地方
catalystInstance.getJSModule(AppRegistry.class).runApplication(jsAppModuleName,appParams);
}
再来详细说一下最后一句,(大量代码预警) @Override
public <T extends JavaScriptModule> T getJSModule(ExecutorToken executorToken,Class<T> jsInterface) {
//进入JSModuleRegistry中
return Assertions.assertNotNull(mJSModuleRegistry)
.getJavaScriptModule(this,executorToken,jsInterface);
}
//JavaScriptModuleRegistry.java
public synchronized <T extends JavaScriptModule> T getJavaScriptModule(
CatalystInstance instance,ExecutorToken executorToken,Class<T> moduleInterface) {
HashMap<Class<? extends JavaScriptModule>,JavaScriptModule> instancesForContext =
mModuleInstances.get(executorToken);
if (instancesForContext == null) {
instancesForContext = new HashMap<>();
//缓存一下 方便后面再使用
mModuleInstances.put(executorToken,instancesForContext);
}
JavaScriptModule module = instancesForContext.get(moduleInterface);
if (module != null) {
//命中缓存 直接返回
return (T) module;
}
JavaScriptModuleRegistration registration =
...
//很明显 动态代理 重点关注JavaScriptModuleInvocationHandler的invoke方法
JavaScriptModule interfaceProxy = (JavaScriptModule) Proxy.newProxyInstance(
moduleInterface.getClassLoader(),new Class[]{moduleInterface},new JavaScriptModuleInvocationHandler(executorToken,instance,registration));
instancesForContext.put(moduleInterface,interfaceProxy);
return (T) interfaceProxy;
}
@Override
public @Nullable Object invoke(Object proxy,Method method,@Nullable Object[] args) throws Throwable {
....
//又跑到了CatalystInstanceImpl.java中。。。然后又桥接到了CatalystInstanceImpl.cpp中,同样会调用instance的对应方法,直接看吧
mCatalystInstance.callFunction(
executorToken,mModuleRegistration.getName(),method.getName(),jsArgs
);
return null;
}
void Instance::callJSFunction(ExecutorToken token,std::string&& module,std::string&& method,folly::dynamic&& params) {
callback_->incrementPendingJSCalls();//这个回调不多说
//....接着跟吧
nativeToJsBridge_->callFunction(token,std::move(module),std::move(method),std::move(params));
}
//又会进入executor->callFunction(module,method,arguments);
void JSCExecutor::callFunction(const std::string& moduleId,const std::string& methodId,const folly::dynamic& arguments) {
....
auto result = [&] {
try {
//被桥接到MessageQueue.js的callFunctionReturnFlushedQueue方法
return m_callFunctionReturnFlushedQueueJS->callAsFunction({
Value(m_context,String::createExpectingAscii(moduleId)),Value(m_context,String::createExpectingAscii(methodId)),Value::fromDynamic(m_context,std::move(arguments))
});
} catch (...) {
std::throw_with_nested(
std::runtime_error("Error calling function: " + moduleId + ":" + methodId));
}
}();
//顺便还会调用一下native的 这个会在后面再说一下
callNativeModules(std::move(result));
}
callFunctionReturnFlushedQueue(module,args) {
guard(() => {
//执行js的function
this.__callFunction(module,args);
this.__callImmediates();
});
//取出积攒在queue中的action返回给上面的,最终在java中执行
return this.flushedQueue();
}
__callFunction(module: string,method: string,args: any) {
...
//根据module名,方法名和参数执行js方法
const result = moduleMethods[method].apply(moduleMethods,args);
return result;
}
//那什么时候把js的module注册到moduleMethods中呢
//AppRegistry.js
BatchedBridge.registerCallableModule(
'AppRegistry',AppRegistry
);
//BatchedBridge是啥?
const BatchedBridge = new MessageQueue(
() => global.__fbBatchedBridgeConfig,serializeNativeParams
);
registerCallableModule(name,methods) {
this._callableModules[name] = methods;
}
这里就执行了 runApplication: function(appKey: string,appParameters: any): void {
...
runnables[appKey].run(appParameters);
},//而runnables是在什么时候被添加的??下面
registerComponent: function(appKey: string,getComponentFunc: ComponentProvider): string {
runnables[appKey] = {
run: (appParameters) =>
renderApplication(getComponentFunc(),appParameters.initialProps,appParameters.rootTag)
};
return appKey;
},//而registerComponent什么时候被调用的就不用说了吧
到此真正执行到了 通信机制上面关于 简单画了个图 渲染原理现在以一个 import {
Image,} from 'react-native';
这时候 const ReactNative = {
...
get Image() { return require('Image'); },...
}
...
module.exports = ReactNative;
//Image.android.js
var NativeModules = require('NativeModules');
//NativeModules.js
const NativeModules = {};
Object.keys(RemoteModules).forEach((moduleName) => {
Object.defineProperty(NativeModules,moduleName,{
configurable: true,enumerable: true,get: () => {
let module = RemoteModules[moduleName];
if (module && typeof module.moduleID === 'number' && global.nativeRequireModuleConfig) {
//nativeRequireModuleConfig映射到JSCExecutor.cpp
const config = global.nativeRequireModuleConfig(moduleName);
module = config && BatchedBridge.processModuleConfig(config,module.moduleID);
RemoteModules[moduleName] = module;
}
Object.defineProperty(NativeModules,{
configurable: true,value: module,});
return module;
},});
});
module.exports = NativeModules;
//cpp
JSCExecutor::nativeRequireModuleConfig->JsToNativeBridge::getModuleConfig->ModuleRegistry::getConfig
folly::dynamic ModuleRegistry::getConfig(const std::string& name) {
...
NativeModule* module = modules_[it->second].get();
...
//最终反射调用JavaModuleWrapper.java的getConstants
folly::dynamic constants = module->getConstants();
...
//最终反射调用JavaModuleWrapper.java的getMethods
//返回对应module中所有@ReactMethod注解的方法
std::vector<MethodDescriptor> methods = module->getMethods();
//modules_在哪赋值?
//ModuleRegistryHolder.cpp构造函数,这个类上面有提到,回去看看
//registry_ = std::make_shared<ModuleRegistry>(std::move(modules));
}
然后返回到 然后当调用 __nativeCall(module,params,onFail,onSucc) {
...
this._queue[MODULE_IDS].push(module);
this._queue[METHOD_IDS].push(method);
this._queue[PARAMS].push(preparedParams);
...
//如果5ms内有多个方法调用就先待在队列里防止过高频率,否则调用C++的nativeFlushQueueImmediate方法
if (global.nativeFlushQueueImmediate &&
now - this._lastFlush >= MIN_TIME_BETWEEN_FLUSHES_MS) {
global.nativeFlushQueueImmediate(this._queue);
this._queue = [[],[],this._callID];
this._lastFlush = now;
}
}
上面把 下面再说一下 appParams.putDouble("rootTag",initialProps);
把 这个 final int tag = mNextRootViewTag;//默认是1
mNextRootViewTag += ROOT_VIEW_TAG_INCREMENT;//10
也就是默认的 再通过这个 ReactNative.render(
<AppContainer> <RootComponent {...initialProps} rootTag={rootTag} /> </AppContainer>,rootTag );
这里的 //ReactNative.js
var render = function (element,mountInto,callback) {
return ReactNativeMount.renderComponent(element,callback);
};
这里面的逻辑快到
具体组合的逻辑基本都在上面连个类里面。下面来到 var tag = ReactNativeTagHandles.allocateTag();//给每个view生成一个唯一的tag
...
UIManager.createView(tag,this.viewConfig.uiViewClassName,nativeTopRootTag,updatePayload);
//ReactNativeTagHandles.js
allocateTag: function () {
//排除已经给分配给rootTag的 类似1,11,21
//下面的就是简单的自增,初始化是1
while (this.reactTagIsNativeTopRootID(ReactNativeTagHandles.tagCount)) {
ReactNativeTagHandles.tagCount++;
}
var tag = ReactNativeTagHandles.tagCount;
ReactNativeTagHandles.tagCount++;
return tag;
},
看名字也知道这里就到了创建 @ReactMethod
//创建view的tag,对应native的组件类名,要加入的根布局tag,创建view需要的参数
public void createView(int tag,String className,int rootViewTag,ReadableMap props) {
mUIImplementation.createView(tag,className,rootViewTag,props);
}
在 事件驱动在说 下面简单贴一下
再看一下
在 现在举个例子,点击一下 ...
EventDispatcher eventDispatcher = reactContext.getNativeModule(UIManagerModule.class)
.getEventDispatcher();
mJSTouchDispatcher.handleTouchEvent(event,eventDispatcher);
//JSTouchDispatcher.java
public void handleTouchEvent(MotionEvent ev,EventDispatcher eventDispatcher) {
//这里面分为down,up move 等事件类别
mTargetTag = TouchTargetHelper.findTargetTagAndCoordinatesForTouch(
ev.getX(),ev.getY(),mRootViewGroup,mTargetCoordinates,null);
eventDispatcher.dispatchEvent(
TouchEvent.obtain(
mTargetTag,TouchEventType.START,ev,mGestureStartTime,mTargetCoordinates[0],mTargetCoordinates[1],mTouchEventCoalescingKeyHelper));
}
最终包装成一个 mEventStaging.add(event);//ArrayList<Event>
把事件添加到一个待发送的列表里面。那什么是去处发送?是在 @Override
public void doFrame(long frameTimeNanos) {
....
moveStagedEventsToDispatchQueue();
...
mReactContext.runOnJSQueueThread(mDispatchEventsRunnable);
}
调用 @Override
public void run() {
for (int eventIdx = 0; eventIdx < mEventsToDispatchSize; eventIdx++) {
Event event = mEventsToDispatch[eventIdx];
....
event.dispatch(mRCTEventEmitter);
event.dispose();
...
}
}
->TouchEvent.dispatch->TouchesHelper.sendTouchEvent->rctEventEmitter.receiveTouches(
type.getJSEventName(),pointers,changedIndices);
而 简单点就是 脚本执行这里简单说说 至于为啥不都使用 还有其他的跨平台框架,例如 最后再贴一下简单画的思维导图吧 思维导图 参考: facebook/react-native ps:因为本人能力实在有限,上面很多都是连蒙带猜,算是个笔记性质的流水账,有用就看看,没用就算了,欢迎指出错误。 pps这篇本该在两星期之前完成的工作,一直拖到了现在。( (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |