Android React Native多ReactInstanceManager的使用

一、什么是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时会重新创建
相关推荐
卸任6 小时前
Vibe coding工具使用心得
前端·ai编程
brien96 小时前
为什么模型标称 1M,Google Antigravity 聊到 256K 却突然失忆?我们给它做了个原生行内监控圆环
前端
修炼的dance7 小时前
录屏关键帧间隔多少合适?六档实测,2秒到10秒小了75.6%
前端
Lank_M7 小时前
关键帧从1秒拉到10秒,录屏小87.3%,摄像头小10.8%
前端
补码缩写7 小时前
用 ffprobe 拆录屏,八成字节在 29 个关键帧上
前端
百思不得小李7 小时前
一个复杂的动态表单是如何实现的
前端·设计模式
陈随易7 小时前
Cmder 停更 17 个月,2.0 支持 Windows Terminal
前端·后端·程序员
风骏时光牛马7 小时前
前沿视界
前端
kyriewen7 小时前
我扫了 814 个依赖,97 个还敢要 Node 10
前端·javascript·程序员
陈随易8 小时前
3000 万人在用的翻译插件,重写一遍就是一门生意
前端·后端·程序员