一、什么是ReactInsanceManager
ReactInstanceManager是React Native在Android端的核心管理类,负责:
- 创建和管理
JavaScript
运行环境(JS Engine, 如Hermes或JSC) - 管理React Native的
Bridge
机制,用于JavaScript和原生代码通信 - 加载JavaScript
Bundle
(如index.android.bundle) - 维护Native组件和React组件的生命周期(Activity/Fragment之间的通信)
二、为什么需要使用多ReactInstanceManager
✅ 多个页面之间都会操作全局状态,为了避免互相影响,需要使用多实例进行隔离。
✅ 需要有独立的JS逻辑
三、如何实现多ReactInstanceManager
1. ReactRootView
kotlin
//in MainActivity.kt
private fun initRootView1() {
val newReactInstanceManager = ReactInstanceManager
.builder()
.setApplication(application) //绑定Application
.setCurrentActivity(this) //绑定Activity
.setBundleAssetName("index.android.bundle") //指定JS Bundle
.setJSMainModulePath("index") //指定JS入口文件
.addPackage(MainReactPackage()) //加载默认的RN组件
.setUseDeveloperSupport(BuildConfig.DEBUG) //是否开启开发者模式
.setInitialLifecycleState(LifecycleState.RESUMED) //设置初始生命周期
.build()
val rootView = ReactRootView(this)
rootView.startReactApplication(
newReactInstanceManager,
"MyFirstRNDemo",
Bundle().apply {
putInt("pageType", 1)
}
)
binding.rootView1.addView(
rootView,
0,
FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT)
)
binding.destroyBt1.setOnClickListener {
Log.d("EANAM", "initRootView1: clear host")
newReactInstanceManager.invalidate()
}
}
2. ReactActivity/ReactFragment
针对ReactActivity/ReactFragment我们需要创建的ReactNativeHost容器来提供独立的ReactInstanceManager实例
- 重写ReactActivity的createReactActivityDelegate,避免使用Application中创建的ReactNativeHost对象
kotlin
/**
* Returns the instance of the [ReactActivityDelegate]. We use [DefaultReactActivityDelegate]
* which allows you to enable New Architecture with a single boolean flags [fabricEnabled]
*/
override fun createReactActivityDelegate(): ReactActivityDelegate {
return object: ReactActivityDelegate(this, this.mainComponentName) {
override fun getReactNativeHost(): ReactNativeHost {
return object: DefaultReactNativeHost(application) {
override fun getPackages() = PackageList(application).packages
override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG
}
}
}
}
- 重新ReactFragment的getReactNativeHost方法
kotlin
override fun getReactNativeHost(): ReactNativeHost {
return object: DefaultReactNativeHost(MainApplication.app) {
override fun getPackages() = PackageList(application).packages
override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG
}
}
四、React Native实例的生命周期
正常情况下,我们在Application中会实现一个ReactNativeHost变量,这个变量持有的ReactInstanceManager会在整个应用生命周期中都存在,所以这个不需要我们去销毁。
而其他情况下(多ReactInstanceManager/ReactNativeHost),React Native没有自动销毁的机制,所以需要我们去手动调用。
kotlin
newReactInstanceManager.invalidate()
kotlin
reactNativeHost.clear()
五、共用的ReactInstanceManager被销毁会怎么样?
1. 调用ReactInstanceManager.invalidate()销毁
- 已展示的视图正常展示,但是点击、触摸事件不会被处理,因为js引擎已被销毁
- 重新触发ReactRootView.startApplication,传入同一个ReactInsatanceManager无法加载视图
2. 直接调用ReactNativeHost.clear()销毁
- 已展示的视图正常展示,但是点击、触摸事件不会被处理,因为js引擎已被销毁
- 重新触发使用ReactNativeHost的Activity/Fragment展示,表现正常
- 重新触发可以展示的原因:
- ReactNativeHost.clear会销毁并置空ReactInstanceManager
- Activity/Fragment调用ReactNativeHost.getReactInstanceManager时会重新创建
- ReactNativeHost.clear会销毁并置空ReactInstanceManager