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/