You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于ReactApplication的原生Android应用如何加载多React Native Bundle?

在原生Android应用中加载多个React Native Bundle(兼容react-navigation)

核心思路

由于ReactApplication接口要求返回单一ReactNativeHost,但我们可以通过为每个Bundle创建独立的ReactNativeHost实例,并让自定义ReactActivity根据需求选择对应的Host,实现多Bundle的隔离加载。同时保持对react-navigation的兼容,因为ReactActivity的生命周期依然能满足导航需求。

实现步骤

1. 在Application中管理多个ReactNativeHost

在自定义Application中,为每个Bundle创建独立的ReactNativeHost,并通过Map存储以便后续获取:

class MyCoolApplication : Application(), ReactApplication {
    private val reactHostMap = mutableMapOf<String, ReactNativeHost>()

    override fun onCreate() {
        super.onCreate()
        // 初始化两个Bundle对应的Host
        reactHostMap["mycoolapp1.bundle"] = createReactHost("mycoolapp1.bundle")
        reactHostMap["mycoolapp2.bundle"] = createReactHost("mycoolapp2.bundle")
    }

    private fun createReactHost(bundleName: String): ReactNativeHost {
        return object : DefaultReactNativeHost(this) {
            override fun getBundleAssetName(): String? = bundleName

            override fun getJSMainModuleName(): String = "index"

            override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG

            override fun getPackages(): List<ReactPackage> {
                return PackageList(this).packages.apply {
                    // 在此添加自定义RN原生包,所有Bundle共享的包只需添加一次
                }
            }
        }
    }

    // 对外提供获取指定Bundle对应Host的方法
    fun getReactHostForBundle(bundleName: String): ReactNativeHost? = reactHostMap[bundleName]

    // 实现ReactApplication接口的默认Host返回(可选,用任意一个Bundle的Host即可)
    override fun getReactNativeHost(): ReactNativeHost = reactHostMap["mycoolapp1.bundle"]!!
}

2. 自定义ReactActivity以支持动态选择Host

创建自定义ReactActivity,重写getReactNativeHost和getMainComponentName方法,根据启动时传递的Bundle参数选择对应的Host和RN组件名:

class CustomRNActivity : ReactActivity() {
    companion object {
        const val EXTRA_BUNDLE_NAME = "bundle_name"
        const val EXTRA_COMPONENT_NAME = "component_name"
    }

    override fun getReactNativeHost(): ReactNativeHost {
        val bundleName = intent.getStringExtra(EXTRA_BUNDLE_NAME) ?: "mycoolapp1.bundle"
        return (application as MyCoolApplication).getReactHostForBundle(bundleName)!!
    }

    override fun getMainComponentName(): String? {
        // 可以直接通过Intent传递组件名,或根据Bundle名称映射
        return intent.getStringExtra(EXTRA_COMPONENT_NAME) ?: when(val bundleName = intent.getStringExtra(EXTRA_BUNDLE_NAME)) {
            "mycoolapp1.bundle" -> "MyCoolApp1"
            "mycoolapp2.bundle" -> "MyCoolApp2"
            else -> "MyCoolApp1"
        }
    }
}

3. 启动对应Bundle的RN页面

在原生Android页面中,通过Intent传递Bundle名称和组件名,启动自定义的CustomRNActivity:

// 加载第一个RN Bundle
startActivity(Intent(this, CustomRNActivity::class.java).apply {
    putExtra(CustomRNActivity.EXTRA_BUNDLE_NAME, "mycoolapp1.bundle")
    putExtra(CustomRNActivity.EXTRA_COMPONENT_NAME, "MyCoolApp1")
})

// 加载第二个RN Bundle
startActivity(Intent(this, CustomRNActivity::class.java).apply {
    putExtra(CustomRNActivity.EXTRA_BUNDLE_NAME, "mycoolapp2.bundle")
    putExtra(CustomRNActivity.EXTRA_COMPONENT_NAME, "MyCoolApp2")
})

4. 打包RN Bundle(注意事项)

为每个RN项目打包时,指定不同的Bundle文件名,避免冲突:

# 打包第一个RN应用
react-native bundle --platform android --dev false --entry-file index.js --bundle-output ../android/app/src/main/assets/mycoolapp1.bundle --assets-dest ../android/app/src/main/res/react1

# 打包第二个RN应用
react-native bundle --platform android --dev false --entry-file index.js --bundle-output ../android/app/src/main/assets/mycoolapp2.bundle --assets-dest ../android/app/src/main/res/react2

若两个RN应用的资源(图片、字符串等)存在命名冲突,需将资源打包到不同的res子目录(如上述的react1、react2),并在Android项目中配置资源目录:
在app/build.gradle中添加:

sourceSets {
    main {
        res.srcDirs += 'src/main/res/react1'
        res.srcDirs += 'src/main/res/react2'
    }
}

关键优势

  • 每个Bundle拥有独立的ReactInstanceManager,JS环境完全隔离,避免状态污染
  • 保持对react-navigation的兼容,ReactActivity的生命周期能满足RN导航的需求
  • 原生模块可通过共享Package列表实现复用,减少冗余代码

内容的提问来源于stack exchange,提问作者Mando

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 12:18:18