0.70官方文档:reactnative.dev/docs/0.70/t…
- 以下基于 react-native@0.70.6 分析
- 并参考github.com/Sunbreak/re…
- Schema
{
"modules": {
"NativeTurboOnly": {
"type": "NativeModule",
"aliases": {},
"spec": {
"properties": [
{
"name": "multiply",
"optional": false,
"typeAnnotation": {
"type": "FunctionTypeAnnotation",
"returnTypeAnnotation": {
"type": "NumberTypeAnnotation"
},
"params": [
{
"name": "a",
"optional": false,
"typeAnnotation": {
"type": "NumberTypeAnnotation"
}
},
{
"name": "b",
"optional": false,
"typeAnnotation": {
"type": "NumberTypeAnnotation"
}
}
]
}
}
]
},
"moduleNames": [
"TurboOnly"
]
}
}
}
Android library codegen
$ tree ${NODE_MODULES}/${LIBRARY}/android/build/generated/source/codegen
├── java
│ └── com
│ └── turboonly
│ └── NativeTurboOnlySpec.java
├── jni
│ ├── Android.mk
│ ├── CMakeLists.txt
│ ├── RNTurboOnlySpec-generated.cpp
│ ├── RNTurboOnlySpec.h
│ └── react
│ └── renderer
│ └── components
│ └── RNMyModSpec
│ ├── RNTurboOnlySpecJSI-generated.cpp
│ └── RNTurboOnlySpecJSI.h
└── schema.json
Turbo版本的BaseJavaModule
NativeTurboOnlySpec.java
$ tree ${NODE_MODULES}/${LIBRARY}/android
├── build
│ └── generated
│ └── source
│ └── codegen
│ └── java
│ └── com
│ └── turboonly
│ └── NativeTurboOnlySpec.java
└── build.gradle
turbo-only通过library codegen的NativeTurboOnlySpec.java
public abstract class NativeTurboOnlySpec extends ReactContextBaseJavaModule implements ReactModuleWithSpec, TurboModule {
@ReactMethod(isBlockingSynchronousMethod = true)
@DoNotStrip
public abstract double multiply(double a, double b);
}
turbo-only的android/build.gradle,github.com/Sunbreak/re…
android {
sourceSets {
main {
if (isNewArchitectureEnabled()) {
java.srcDirs += [
// This is needed to build Kotlin project with NewArch enabled
"${project.buildDir}/generated/source/codegen/java"
]
}
}
}
}
RNTurboOnlySpec.h/cpp
$ tree ${NODE_MODULES}/${LIBRARY}/android
└── build
└── generated
└── source
└── codegen
└── jni
├── Android.mk
├── CMakeLists.txt
├── RNTurboOnlySpec-generated.cpp
└── RNTurboOnlySpec.h
turbo-only通过library codegen的RNTurboOnlySpec-generated.cpp
#include "RNTurboOnlySpec.h"
static facebook::jsi::Value __hostFunction_NativeTurboOnlySpecJSI_multiply(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
static jmethodID cachedMethodId = nullptr;
return static_cast<JavaTurboModule &>(turboModule).invokeJavaMethod(rt, NumberKind, "multiply", "(DD)D", args, count, cachedMethodId);
}
NativeTurboOnlySpecJSI::NativeTurboOnlySpecJSI(const JavaTurboModule::InitParams ¶ms)
: JavaTurboModule(params) {
methodMap_["multiply"] = MethodMetadata {2, __hostFunction_NativeTurboOnlySpecJSI_multiply};
}
std::shared_ptr<TurboModule> RNTurboOnlySpec_ModuleProvider(const std::string &moduleName, const JavaTurboModule::InitParams ¶ms) {
if (moduleName == "TurboOnly") {
return std::make_shared<NativeTurboOnlySpecJSI>(params);
}
return nullptr;
}
Turbo版本的CxxModuleWrapper
参考[ReactNative笔记]my-mod适配legecy TurboCxxModule
不依赖library codegen,底层使用TurboCxxModule.h/cpp转义folly::dynamic和jsi::Value
pure TurboCxxModule
参考[ReactNative笔记]my-mod适配pure TurboCxxModule
$ tree ${NODE_MODULES}/${LIBRARY}/android/build/generated/source/codegen
└── jni
└── react
└── renderer
└── components
└── RNMyModSpec
├── RNTurboOnlySpecJSI-generated.cpp
└── RNTurboOnlySpecJSI.h
- react-native-my-mod.h
#include "RNMyModSpecJSI.h"
class MyModCxxModule : public NativeMyModCxxSpecJSI {
public:
MyModCxxModule(std::shared_ptr<CallInvoker> jsInvoker);
void multiply(Runtime &rt, double a, double b, Function callback) override;
};
- MainModuleManagerDelegate.cpp
#include <react-native-my-mod.h>
std::shared_ptr<TurboModule>
MainApplicationTurboModuleManagerDelegate::getTurboModule(
const std::string &name,
const std::shared_ptr<CallInvoker> &jsInvoker) {
if (name == "MyMod") {
return std::make_shared<mymod::MyModCxxModule>(jsInvoker);
}
// Not implemented yet: provide pure-C++ NativeModules here.
return nullptr;
}
std::shared_ptr<TurboModule>
MainApplicationTurboModuleManagerDelegate::getTurboModule(
const std::string &name,
const JavaTurboModule::InitParams ¶ms) {
return MainApplicationModuleProvider(name, params);
}
Android APP Autolink
0.70的CMakeLists.txt
0.70的library官方文档:reactnative.dev/docs/0.70/n…
0.70的APP官方文档:reactnative.dev/docs/0.70/n…
$ tree ${APP}/android/app
├── build
│ └── generated
│ └── rncli
│ └── src
│ └── main
│ └── jni
│ ├── Android-rncli.cmake
│ ├── Android-rncli.mk
│ ├── rncli.cpp
│ └── rncli.h
├── build.gradle
└── src
└── main
└── jni
└── CMakeLists.txt
graph TD
subgraph example
build.gradle --> app-cmake[CMakeLists.txt]
Android-rncli.cmake
end
app-cmake --> ReactNative-application.cmake --> Android-rncli.cmake
ReactNative-application.cmake --> Android-prebuilt.cmake
subgraph turbo-only
lib-cmake[CMakeLists.txt]
end
Android-rncli.cmake --> lib-cmake
-
turbo-only的example/android/app/build.gradle,github.com/Sunbreak/re… -
turbo-only的example/android/app/src/main/jni/CMakeLists.txt,github.com/Sunbreak/re… -
react-native的ReactAndroid/cmake-utils/ReactNative-application.cmake,github.com/facebook/re… -
turbo-only的example通过APP autolink的Android-rncli.cmake
add_subdirectory(/Users/sunbreak/w/Sunbreak/reactnative-turbo.trial/turbo-only/android/build/generated/source/codegen/jni/ RNTurboOnlySpec_autolinked_build)
set(AUTOLINKED_LIBRARIES
react_codegen_RNTurboOnlySpec
)
0.69的Android.mk
0.69的library官方文档:reactnative-archive-august-2023.netlify.app/docs/0.69/n…
0.69的APP官方文档:reactnative-archive-august-2023.netlify.app/docs/0.69/n…
react-native@0.69.x使用@react-native-community/cli@8.x,Autolink仅生成PackageList.java,没有Android-rncli.mk
$ tree ${APP}/android/app
├── build.gradle
└── src
└── main
└── jni
└── Android.mk
graph TD
subgraph APP
build.gradle --> app-mk[Android.mk]
end
app-mk --> Android-prebuilt.mk
subgraph library
lib-mk[Android.mk]
end
-
MyReactNative@0.69.4的android/app/build.gradle,github.com/Sunbreak/re…
-
MyReactNative@0.69.4的android/app/src/main/jni/Android.mk,github.com/Sunbreak/re…
-
react-native的ReactAndroid/Android-prebuilt.mk,github.com/facebook/re…
TurboModuleManager调用链路
Application启动
graph TD
onCreate --> useTurboModules[useTurboModules = true]
subgraph MainApplication
onCreate
end
onCreate --> getReactInstanceManager
subgraph MainApplicationReactNativeHost
getReactInstanceManager --> createReactInstanceManager --> getReactPackageTurboModuleManagerDelegateBuilder
getReactPackageTurboModuleManagerDelegateBuilder
end
getReactPackageTurboModuleManagerDelegateBuilder --> Builder
subgraph MainApplicationTurboModuleManagerDelegate
Builder
end
Activity启动
graph LR
subgraph MainActivity
act-onCreate[onCreate]
end
act-onCreate --> dlg-onCreate
subgraph MainActivityDelegate
dlg-onCreate[onCreate] --> actdlg-loadApp[loadApp]
end
actdlg-loadApp --> dlg-loadApp
subgraph ReactDelegate
dlg-loadApp[loadApp]
end
dlg-loadApp --> startReactApplication
subgraph ReactRootView
startReactApplication
end
startReactApplication --> createReactContextInBackground
subgraph ReactInstanceManager
createReactContextInBackground
end
- TurboModuleManager初始化
graph TD
createReactContextInBackground --> recreateReactContextInBackgroundInner
recreateReactContextInBackgroundInner --> recreateReactContextInBackgroundFromBundleLoader
recreateReactContextInBackgroundFromBundleLoader --> recreateReactContextInBackground
recreateReactContextInBackground --> runCreateReactContextOnNewThread
runCreateReactContextOnNewThread --> createReactContext
private ReactApplicationContext createReactContext(
JavaScriptExecutor jsExecutor, JSBundleLoader jsBundleLoader) {
...
if (ReactFeatureFlags.useTurboModules && mTMMDelegateBuilder != null) {
TurboModuleManagerDelegate tmmDelegate =
mTMMDelegateBuilder
.setPackages(mPackages)
.setReactApplicationContext(reactContext)
.build();
TurboModuleManager turboModuleManager =
new TurboModuleManager(
catalystInstance.getRuntimeExecutor(),
tmmDelegate,
catalystInstance.getJSCallInvokerHolder(),
catalystInstance.getNativeCallInvokerHolder());
catalystInstance.setTurboModuleManager(turboModuleManager);
TurboModuleRegistry registry = (TurboModuleRegistry) turboModuleManager;
// Eagerly initialize TurboModules
for (String moduleName : registry.getEagerInitModuleNames()) {
registry.getModule(moduleName);
}
}
...
}
找到needsEagerInit的TurboModule
graph LR
subgraph TurboModuleManager
mgr-getEagerInitModuleNames[getEagerInitModuleNames]
end
mgr-getEagerInitModuleNames --> dlg-getEagerInitModuleNames
subgraph ReactPackageTurboModuleManagerDelegate
dlg-getEagerInitModuleNames[getEagerInitModuleNames]
end
@Override
public List<String> getEagerInitModuleNames() {
List<String> moduleNames = new ArrayList<>();
for (TurboReactPackage reactPackage : mPackages) {
for (ReactModuleInfo moduleInfo :
reactPackage.getReactModuleInfoProvider().getReactModuleInfos().values()) {
if (moduleInfo.isTurboModule() && moduleInfo.needsEagerInit()) {
moduleNames.add(moduleInfo.name());
}
}
}
return moduleNames;
}
TurboModuleManager初始化
生成provider绑定proxy
graph TD
subgraph TurboModuleBinding.cpp
install -..->|build| jsProxy
end
installJSIBindings --> install
jsProxy --> turboModuleProvider
subgraph TurboModuleManager.cpp
installJSIBindings -..->|build| turboModuleProvider
end
provider生成TurboModule.cpp
- 调用链
graph TD
subgraph TurboModuleManager
subgraph mgr-cpp
turboModuleProvider
end
subgraph mgr-java
getJavaModule
getLegecyCxxModule
end
end
turboModuleProvider --> getLegecyCxxModule -..->|CxxModuleWrapper.java| wrp-getModule
turboModuleProvider --> wrp-getModule
subgraph CxxModuleWrapper.cpp
wrp-getModule([getModule])
end
turboModuleProvider --> getTurboModule-js
turboModuleProvider --> getTurboModule-java
turboModuleProvider --> getJavaModule -..->|TurboModule.java| getTurboModule-java
subgraph MainModuleManagerDelegate.cpp
getTurboModule-js(["getTurboModule(jsInvoker)"])
getTurboModule-java(["getTurboModule(javaParams)"])
end
wrp-getModule -..->|cxxModule| ctor-cxx
turboModuleProvider --> ctor-cxx
subgraph TurboCxxModule.cpp
ctor-cxx(["TurboCxxModule(jsInvoker)"])
end
getTurboModule-java --> ctor-java
subgraph JavaTurboModule.cpp
ctor-java(["JavaTurboModule(javaParams)"])
end
- 管理类图
classDiagram
class mgrJava["TurboModuleManager.java"] {
-delegate
+getEagerInitModuleNames()
+getLegecyCxxModule()
+getJavaModule()
-installJSIBindings()
}
mgrJava <|.. mgrCpp: Composition
class mgrCpp["TurboModuleManager.cpp"] {
-delegate_
-installJSIBindings()
}
mgrDlgJava .. mgrJava
class mgrDlgJava["TurboModuleManagerDelegate.java"] {
+getModule()*
+getLegecyCxxModule()*
+getEagerInitModuleNames()
}
mgrDlgJava <|.. mgrDlgCpp: Composition
mgrDlgCpp .. mgrCpp
class mgrDlgCpp["TurboModuleManagerDelegate.cpp"] {
+getTurboModule(jsInvoker)*
+getTurboModule(javaParams)*
}
mgrDlgJava <|-- rctMgrDlgJava
class rctMgrDlgJava["ReactPackageTurboModuleManagerDelegate.java"] {
+getModule()
+getLegecyCxxModule()
-resolveModule()
+getEagerInitModuleNames()
}
rctMgrDlgJava <|-- mainMgrDlgJava
class mainMgrDlgJava["MainModuleManagerDelegate.java"] {
-canCreateTurboModule()
}
mainMgrDlgJava <|.. mainMgrDlgCpp: Composition
mgrDlgCpp <|-- mainMgrDlgCpp
class mainMgrDlgCpp["MainModuleManagerDelegate.cpp"] {
+getTurboModule(jsInvoker)
+getTurboModule(javaParams)
-canCreateTurboModule()
}
- 数据类图
classDiagram
wrpBaseJava <|.. wrpBaseCpp: Composition
class wrpBaseJava["CxxModuleWrapperBase.java"] {
+getName()
}
class wrpBaseCpp["CxxModuleWrapperBase.cpp"] {
+getName()*
+getModule()*
}
wrpJava <|.. wrpCpp: Composition
wrpBaseJava <|-- wrpJava
class wrpJava["CxxModuleWrapper.java"] {
+makeDsoNative()$
}
wrpBaseCpp <|-- wrpCpp
class wrpCpp["CxxModuleWrapper.cpp"] {
+makeDsoNative()$
+getName()
+getModule(): CxxModule
}
CxxModule .. wrpCpp
CxxModule .. TurboCxxModule
class CxxModule["CxxModule.cpp"]
class jsi_HostObject["jsi::HostObject.cpp"] {
+get(propName)*
}
jsi_HostObject <|-- TurboModule
class TurboModule["TurboModule.cpp"] {
+get(propName)*
}
TurboModule <|-- TurboCxxModule
class TurboCxxModule["TurboCxxModule.cpp"] {
-cxxModule_: CxxModule
+get(propName)*
+invokeMethod()
}
TurboModule <|-- JavaTurboModule
class JavaTurboModule["JavaTurboModule.cpp"] {
-instance_: JTurboModule
+JavaTurboModule(javaParams)
+invokeJavaMethod()
}
JTurboModule .. JavaTurboModule
class JTurboModule["JTurboModule.cpp"]
class TurboModuleJava["TurboModule.java"]
TurboModuleJava <|.. JTurboModule: Composition
provider搜索TurboModule.java
graph TD
subgraph TurboModuleManager
subgraph mgr-java
getJavaModule --> mgr-getModule
getLegecyCxxModule --> mgr-getModule[getModule]
mgr-getModule([getModule]) --> getOrCreateModule
end
subgraph mgr-cpp
turboModuleProvider
end
turboModuleProvider --> getJavaModule
turboModuleProvider --> getLegecyCxxModule
end
getOrCreateModule --> dlg-getModule
getOrCreateModule --> dlg-getCxxModule
subgraph ReactPackageTurboModuleManagerDelegate.java
dlg-getModule([getModule]) --> resolveModule
dlg-getCxxModule([getCxxModule]) --> resolveModule
end
resolveModule --> pkg-getModule
subgraph TurboReactPackage.java
pkg-getModule([getModule])
end