做了2年React Native,之前也看过一些Android 方面的文章,自己也都只是看了个大概,也就是一知半解,现在想着自己看一遍,好提升一下自己。 我文笔不怎么好,这个主要是用于自己学习记录的。
我们都知道一个RN项目创建出来的时候Android 原生会有2个文件 一个MainActivity,一个MainApplication。现在我们来看看MainApplication做的什么东西。
MainApplication
public class MainApplication extends Application implements ReactApplication {
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
@Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
@Override
protected List<ReactPackage> getPackages() {
@SuppressWarnings("UnnecessaryLocalVariable")
List<ReactPackage> packages = new PackageList(this).getPackages();
// Packages that cannot be autolinked yet can be added manually here, for example:
// packages.add(new MyReactNativePackage());
return packages;
}
@Override
protected String getJSMainModuleName() {
return "index";
}
};
@Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
@Override
public void onCreate() {
super.onCreate();
SoLoader.init(this, /* native exopackage */ false);
}
}
这个Application 会 实现一个接口 ReactApplication
public interface ReactApplication {
/**
* Get the default {@link ReactNativeHost} for this app.
*/
ReactNativeHost getReactNativeHost();
}
这个接口值生命了一个方法,很简单。
然后我们在去看MainApplication 里面实现了getReactNativeHost 这个方法 返回了在MainApplication中生命的 ReactNativeHost(mReactNativeHost)
ReactNativeHost
public abstract class ReactNativeHost {
private final Application mApplication; // Application上下文对象
private @Nullable ReactInstanceManager mReactInstanceManager; // ReactInstanceManager实例
protected ReactNativeHost(Application application) {
mApplication = application; // 实例化的时候将 application 传入并持有
}
/**
*获得当前的ReactInstanceManager, 如果没有则进行创建
*/
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;
}
/**
* 判断当前的ReactNativeHost是否持用ReactInstanceManager实例
*/
public boolean hasInstance() {
return mReactInstanceManager != null;
}
/**
* 销毁当前持有的ReactInstanceManager实例
*/
public void clear() {
if (mReactInstanceManager != null) {
mReactInstanceManager.destroy();
mReactInstanceManager = null;
}
}
protected ReactInstanceManager createReactInstanceManager() {
ReactMarker.logMarker(ReactMarkerConstants.BUILD_REACT_INSTANCE_MANAGER_START);
// 通过Builder设计模式,来构建ReactInstanceManager实例
ReactInstanceManagerBuilder builder = ReactInstanceManager.builder()
.setApplication(mApplication)
.setJSMainModulePath(getJSMainModuleName())
.setUseDeveloperSupport(getUseDeveloperSupport())
.setRedBoxHandler(getRedBoxHandler())
.setJavaScriptExecutorFactory(getJavaScriptExecutorFactory())
.setUIImplementationProvider(getUIImplementationProvider())
.setJSIModulesPackage(getJSIModulePackage())
.setInitialLifecycleState(LifecycleState.BEFORE_CREATE);
// 将 getPackages 中注册的ReactPackage 都注册到 ReactInstanceManager 中
for (ReactPackage reactPackage : getPackages()) {
builder.addPackage(reactPackage);
}
// 这个方法是用于 如果你的jsbundle 不是放在assets中的时候可以指定bundle加载的路径
String jsBundleFile = getJSBundleFile();
if (jsBundleFile != null) {
builder.setJSBundleFile(jsBundleFile);
} else { // Assertions.assertNotNull(getBundleAssetName()) 这个方法仅仅只是判断 getBundleAssetName() 的 返回结果是否为null
builder.setBundleAssetName(Assertions.assertNotNull(getBundleAssetName()));
}
ReactInstanceManager reactInstanceManager = builder.build();
ReactMarker.logMarker(ReactMarkerConstants.BUILD_REACT_INSTANCE_MANAGER_END);
return reactInstanceManager; // 返回 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.
*
* 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 the packager server. 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 the packager server.
* 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();
}

本文深入探讨了ReactNative项目中MainApplication类的作用,详细解释了其如何通过ReactApplication接口实现ReactNativeHost,以及ReactNativeHost如何管理和创建ReactInstanceManager,从而理解ReactNative的启动流程。
299

被折叠的 条评论
为什么被折叠?



