-
I'm developing a Super App using React Native, where each MiniApp is dynamically loaded as a standalone JSBundle. The application is performing well on version 0.74 private fun initReactInstanceManager(
bundleAssetName: String = "index.android.bundle",
jsBundleFile: String = "assets://index.android.bundle",
jsMainModulePath: String = "index"
) {
val packages: ArrayList<ReactPackage> = PackageList(application).packages
packages.add(HiAppReactPackage())
mReactInstanceManager =
ReactInstanceManager.builder().setJavaScriptExecutorFactory(HermesExecutorFactory())
.setApplication(application).setCurrentActivity(this)
.setBundleAssetName(bundleAssetName)
.setJSBundleFile(jsBundleFile) // for test - load in assets
.setJSMainModulePath(jsMainModulePath).addPackages(packages)
.setUseDeveloperSupport(BuildConfig.DEBUG)
.setInitialLifecycleState(LifecycleState.RESUMED).build()
mReactInstanceManager.addReactInstanceEventListener(reactInstanceEventListener)
} private fun btnLoadJsBundle1() {
if (person != null) {
removeReactInstanceManager()
initReactInstanceManager()
mReactRootView?.unmountReactApplication()
mReactRootView?.startReactApplication(
mReactInstanceManager, "baka3k", buildInitProperties(person!!)
)
contentView.removeAllViews()
contentView.addView(mReactRootView)
} else {
Log.w(TAG, "#btnLoadJsBundle1() person null")
}
} However, when upgrading to 0.76 and enabling newArchitect, these methods no longer work. class MainApplication : Application(), ReactApplication {
override val reactNativeHost: ReactNativeHost =
object : DefaultReactNativeHost(this) {
override fun getPackages(): List<ReactPackage> =
PackageList(this).packages.apply {
// add(MyReactNativePackage())
}
override fun getJSMainModuleName(): String = "index"
override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG
override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED
override fun getBundleAssetName(): String {
val indexbundle =
if (count % 2 == 0) {
"index2.android.bundle"
} else {
"index1.android.bundle"
}
Log.d("MainApplication","#getBundleAssetName(): $indexbundle")
return indexbundle
}
}
} The getBundleAssetName function is still being called, but the bundle package remains unchanged. Thanks & BestRegards, |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 1 reply
-
I haven't had the time to test this yet, but the code to achieve bundle loading from file is the following: class MainApplication : Application(), ReactApplication {
override val reactNativeHost: ReactNativeHost =
object : DefaultReactNativeHost(this) {
override fun getPackages(): List<ReactPackage> =
PackageList(this).packages.apply {
// add(MyReactNativePackage())
}
override fun getJSMainModuleName(): String = "index"
override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG
override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED
override fun getBundleAssetName(): String {
val indexbundle =
if (count % 2 == 0) {
"index2.android.bundle"
} else {
"index1.android.bundle"
}
Log.d("MainApplication","#getBundleAssetName(): $indexbundle")
return indexbundle
}
+ override fun getJSBundleFile(): String = "assets://index.android.bundle"
}
} Also please note that we fixed a bug about bundle loading, which was shipped in 0.76.1: So you'll have to use 0.76.1 in order for this to work correctly. EDIT: Clarified release where fix was shipped |
Beta Was this translation helpful? Give feedback.
-
I checked the version and I'm sure I'm using 0.76.1
And 2 buttons on screen
How can do that? I tried the following override fun getJSBundleFile(): String? {
val indexbundle =
if (count % 2 == 0) {
"/data/data/com.test/files/index1.android.bundle"
} else {
"/data/data/com.test/files/index2.android.bundle"
}
Log.d("MainApplication","#getJSBundleFile(): $indexbundle")
return indexbundle
} But it doesn't work, ReactNativeHost did not load the new bundle file, but reused the old bundle file from the previous time |
Beta Was this translation helpful? Give feedback.
-
Sorry for late,
@OptIn(UnstableReactNativeAPI::class)
private fun createReactHost(bundlePath: String): ReactHost {
reactNativeHost = object : DefaultReactNativeHost(application) {
override fun getPackages(): List<ReactPackage> = PackageList(this).packages.apply {}
override fun getJSMainModuleName(): String = "index"
override fun getUseDeveloperSupport(): Boolean = true
override fun getJSBundleFile(): String? {
return bundlePath
}
override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED
}
val packageList = reactNativeHost!!.reactInstanceManager.packages//PackageList(reactNativeHost).packages
return CustomDefaultReactNativeHost.getDefaultReactHost(
context = application.applicationContext,
packageList = packageList,
jsMainModulePath = "index",
jsBundleAssetPath = null,
jsBundleFilePath = bundlePath,
isHermesEnabled = true,
useDevSupport = true,
jsBundleLoader = null
)
}
private fun loadReactNative(bundlePath: String) {
val bundleFile = File(bundlePath)
reactHost = createReactHost(bundleFile.absolutePath)
if (reactNativeHostSurface == null) {
reactNativeHostSurface = reactHost.createSurface(this, "NewArchitectureTest", null)
bindingReactActivityTest.contentView.addView(reactNativeHostSurface!!.view)
}
reactHost.reload("NewArchitectureTest") // this is magic, please notice that
reactNativeHostSurface?.start()
}
override fun onDestroy() {
cleanReactNative()
super.onDestroy()
}
private fun cleanReactNative() {
bindingReactActivityTest.contentView.removeAllViews()
reactNativeHostSurface?.stop()
reactHost.destroy("NewArchitectureTest", Exception())
reactNativeHostSurface = null
reactNativeHost = null
} It works fine, we can reload JsBundle File However, with this approach, we MUST to re-create another instance for both ReactHost and ReactNativeHost. Is there a way to reload/invalidate the Jsbundle without having to create new instance for ReactHost/ReactNativeHost?" Thanks & Best Regards |
Beta Was this translation helpful? Give feedback.
Ok so that's a different kind of problem as you'll have to effectively reload the app.
You'll have to use the
reload()
method fromReactHost
:https://github.com/facebook/react-native/blob/7211119d2325a67067f9dd7296cdcb9f91624c7f/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactHost.kt#L108
The
ReactHost
is specified in the property you have in the MainApplication:I'm also unsure if the bundle is cached so I'm unsure if this effectively works, we'll have to try. Do you have a sample project I…