1. Android 原生与 JS 互相调用
1.1. V8
1.2. React Native
app/build.gradle:
apply from: "../../node_modules/react-native/react.gradle"
react.gradle:
def cliPath = config.cliPath ?: "node_modules/react-native/local-cli/cli.js"
def bundleAssetName = config.bundleAssetName ?: "index.android.bundle"
def entryFile = config.entryFile ?: "index.android.js"
def bundleCommand = config.bundleCommand ?: "bundle"
def jsBundleFile = file("$jsBundleDir/$bundleAssetName")
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
commandLine("cmd", "/c", *nodeExecutableAndArgs, cliPath, bundleCommand, "--platform", "android", "--dev", "${devEnabled}",
"--reset-cache", "--entry-file", entryFile, "--bundle-output", jsBundleFile, "--assets-dest", resourcesDir, *extraArgs)
} else {
commandLine(*nodeExecutableAndArgs, cliPath, bundleCommand, "--platform", "android", "--dev", "${devEnabled}",
"--reset-cache", "--entry-file", entryFile, "--bundle-output", jsBundleFile, "--assets-dest", resourcesDir, *extraArgs)
}
打包生成 assets/index.android.bundle
in Activity.java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mReactRootView = new ReactRootView(this);
mReactInstanceManager = ReactInstanceManager.builder()
.setApplication(getApplication())
.setBundleAssetName("index.android.bundle")
.setJSMainModuleName("index.android")
.addPackage(new MainReactPackage())
.setUseDeveloperSupport(BuildConfig.DEBUG)
.setInitialLifecycleState(LifecycleState.RESUMED)
.build();
mReactRootView.startReactApplication(mReactInstanceManager, "Basic", null);
setContentView(mReactRootView);
}
- ReactInstanceManager.java: 创建和管理 CatalyInstance 的实例
CatalystInstanceImpl.runJSBundle()
加载 JS Bundle- JavaScriptExecutor JS执行器,将JS的调用传给C++层
in CatalystInstanceImpl.cpp
void CatalystInstanceImpl::jniLoadScriptFromAssets(
) {
}
in Instance.cpp
nativeToJsBridge_->loadApplication(std::move(bundleRegistry), std::move(string),
std::move(sourceURL));
in NativeToJsBridge.cpp
executor->loadApplicationScript(std::move(*startupScript),
std::move(startupScriptSourceURL));
in JSCExecutor.cpp
void JSCExecutor::loadApplicationScript(std::unique_ptr<const JSBigString> script, std::string sourceURL) {
...
//使用Webkit JSC去解释执行JS
evaluateSourceCode(m_context, bcSourceCode, jsSourceURL);
flush();
}
in JSIExecutor.cpp
in JSCRuntime.cpp
#include <JavaScriptCore/JavaScript.h>
in
#include <JavaScriptCore/JavaScript.h>
1.2.1. JavaScriptCore
RN 使用了 webkit/Source/JavaScriptCore/API/