mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
6d6c68c2c6
Summary: Pet Peeve: Metro is a brand name. You don't say "the Metro server" just like you don't say "the iPhone phone". This is a leftover from when it used to be called "the packager server". Note: It makes sense to refer to "the Metro server" when talking about it in the context of Metro's features, like if you are discussing "Metro's bundling" and "Metro's server". However, when talking about the tool itself, just Metro is enough. Changelog: [Internal] Reviewed By: motiz88 Differential Revision: D22330966 fbshipit-source-id: 667618363c641884df543d88cac65d1e44956ad3
157 lines
5.7 KiB
Java
157 lines
5.7 KiB
Java
/*
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*/
|
|
|
|
package com.facebook.react;
|
|
|
|
import android.app.Application;
|
|
import androidx.annotation.Nullable;
|
|
import com.facebook.infer.annotation.Assertions;
|
|
import com.facebook.react.bridge.JSIModulePackage;
|
|
import com.facebook.react.bridge.JavaScriptExecutorFactory;
|
|
import com.facebook.react.bridge.ReactMarker;
|
|
import com.facebook.react.bridge.ReactMarkerConstants;
|
|
import com.facebook.react.common.LifecycleState;
|
|
import com.facebook.react.devsupport.RedBoxHandler;
|
|
import com.facebook.react.uimanager.UIImplementationProvider;
|
|
import java.util.List;
|
|
|
|
/**
|
|
* Simple class that holds an instance of {@link ReactInstanceManager}. This can be used in your
|
|
* {@link Application class} (see {@link ReactApplication}), or as a static field.
|
|
*/
|
|
public abstract class ReactNativeHost {
|
|
|
|
private final Application mApplication;
|
|
private @Nullable ReactInstanceManager mReactInstanceManager;
|
|
|
|
protected ReactNativeHost(Application application) {
|
|
mApplication = application;
|
|
}
|
|
|
|
/** Get the current {@link ReactInstanceManager} instance, or create one. */
|
|
public ReactInstanceManager getReactInstanceManager() {
|
|
if (mReactInstanceManager == null) {
|
|
ReactMarker.logMarker(ReactMarkerConstants.GET_REACT_INSTANCE_MANAGER_START);
|
|
mReactInstanceManager = createReactInstanceManager();
|
|
ReactMarker.logMarker(ReactMarkerConstants.GET_REACT_INSTANCE_MANAGER_END);
|
|
}
|
|
return mReactInstanceManager;
|
|
}
|
|
|
|
/**
|
|
* Get whether this holder contains a {@link ReactInstanceManager} instance, or not. I.e. if
|
|
* {@link #getReactInstanceManager()} has been called at least once since this object was created
|
|
* or {@link #clear()} was called.
|
|
*/
|
|
public boolean hasInstance() {
|
|
return mReactInstanceManager != null;
|
|
}
|
|
|
|
/**
|
|
* Destroy the current instance and release the internal reference to it, allowing it to be GCed.
|
|
*/
|
|
public void clear() {
|
|
if (mReactInstanceManager != null) {
|
|
mReactInstanceManager.destroy();
|
|
mReactInstanceManager = null;
|
|
}
|
|
}
|
|
|
|
protected ReactInstanceManager createReactInstanceManager() {
|
|
ReactMarker.logMarker(ReactMarkerConstants.BUILD_REACT_INSTANCE_MANAGER_START);
|
|
ReactInstanceManagerBuilder builder =
|
|
ReactInstanceManager.builder()
|
|
.setApplication(mApplication)
|
|
.setJSMainModulePath(getJSMainModuleName())
|
|
.setUseDeveloperSupport(getUseDeveloperSupport())
|
|
.setRedBoxHandler(getRedBoxHandler())
|
|
.setJavaScriptExecutorFactory(getJavaScriptExecutorFactory())
|
|
.setUIImplementationProvider(getUIImplementationProvider())
|
|
.setJSIModulesPackage(getJSIModulePackage())
|
|
.setInitialLifecycleState(LifecycleState.BEFORE_CREATE);
|
|
|
|
for (ReactPackage reactPackage : getPackages()) {
|
|
builder.addPackage(reactPackage);
|
|
}
|
|
|
|
String jsBundleFile = getJSBundleFile();
|
|
if (jsBundleFile != null) {
|
|
builder.setJSBundleFile(jsBundleFile);
|
|
} else {
|
|
builder.setBundleAssetName(Assertions.assertNotNull(getBundleAssetName()));
|
|
}
|
|
ReactInstanceManager reactInstanceManager = builder.build();
|
|
ReactMarker.logMarker(ReactMarkerConstants.BUILD_REACT_INSTANCE_MANAGER_END);
|
|
return reactInstanceManager;
|
|
}
|
|
|
|
/** Get the {@link RedBoxHandler} to send RedBox-related callbacks to. */
|
|
protected @Nullable RedBoxHandler getRedBoxHandler() {
|
|
return null;
|
|
}
|
|
|
|
/** Get the {@link JavaScriptExecutorFactory}. Override this to use a custom Executor. */
|
|
protected @Nullable JavaScriptExecutorFactory getJavaScriptExecutorFactory() {
|
|
return null;
|
|
}
|
|
|
|
protected final Application getApplication() {
|
|
return mApplication;
|
|
}
|
|
|
|
/**
|
|
* Get the {@link UIImplementationProvider} to use. Override this method if you want to use a
|
|
* custom UI implementation.
|
|
*
|
|
* <p>Note: this is very advanced functionality, in 99% of cases you don't need to override this.
|
|
*/
|
|
protected UIImplementationProvider getUIImplementationProvider() {
|
|
return new UIImplementationProvider();
|
|
}
|
|
|
|
protected @Nullable JSIModulePackage getJSIModulePackage() {
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Returns the name of the main module. Determines the URL used to fetch the JS bundle from Metro.
|
|
* It is only used when dev support is enabled. This is the first file to be executed once the
|
|
* {@link ReactInstanceManager} is created. e.g. "index.android"
|
|
*/
|
|
protected String getJSMainModuleName() {
|
|
return "index.android";
|
|
}
|
|
|
|
/**
|
|
* Returns a custom path of the bundle file. This is used in cases the bundle should be loaded
|
|
* from a custom path. By default it is loaded from Android assets, from a path specified by
|
|
* {@link getBundleAssetName}. e.g. "file://sdcard/myapp_cache/index.android.bundle"
|
|
*/
|
|
protected @Nullable String getJSBundleFile() {
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Returns the name of the bundle in assets. If this is null, and no file path is specified for
|
|
* the bundle, the app will only work with {@code getUseDeveloperSupport} enabled and will always
|
|
* try to load the JS bundle from Metro. e.g. "index.android.bundle"
|
|
*/
|
|
protected @Nullable String getBundleAssetName() {
|
|
return "index.android.bundle";
|
|
}
|
|
|
|
/** Returns whether dev mode should be enabled. This enables e.g. the dev menu. */
|
|
public abstract boolean getUseDeveloperSupport();
|
|
|
|
/**
|
|
* Returns a list of {@link ReactPackage} used by the app. You'll most likely want to return at
|
|
* least the {@code MainReactPackage}. If your app uses additional views or modules besides the
|
|
* default ones, you'll want to include more packages here.
|
|
*/
|
|
protected abstract List<ReactPackage> getPackages();
|
|
}
|