@@ -4,7 +4,16 @@ import android.app.Application
44import com.facebook.react.ReactHost
55import com.facebook.react.ReactNativeHost
66import com.facebook.react.ReactPackage
7+ import com.facebook.react.bridge.JSBundleLoader
8+ import com.facebook.react.bridge.JSBundleLoaderDelegate
9+ import com.facebook.react.common.annotations.UnstableReactNativeAPI
10+ import com.facebook.react.defaults.DefaultComponentsRegistry
11+ import com.facebook.react.defaults.DefaultReactHostDelegate
12+ import com.facebook.react.defaults.DefaultTurboModuleManagerDelegate
713import com.facebook.react.devsupport.interfaces.RedBoxHandler
14+ import com.facebook.react.fabric.ComponentFactory
15+ import com.facebook.react.runtime.ReactHostImpl
16+ import com.facebook.react.runtime.hermes.HermesInstance
817import com.facebook.react.soloader.OpenSourceMergedSoMapping
918import com.facebook.soloader.SoLoader
1019import com.mendix.mendixnative.error.ErrorHandler
@@ -16,7 +25,6 @@ import com.mendix.mendixnative.react.splash.MendixSplashScreenPresenter
1625import com.mendixnative.MendixNativePackage
1726import java.util.*
1827import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load
19- import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost
2028
2129import com.facebook.react.defaults.DefaultReactNativeHost
2230
@@ -56,8 +64,51 @@ abstract class MendixReactApplication : Application(), MendixApplication, ErrorH
5664 override val isHermesEnabled: Boolean = true
5765 }
5866
59- override val reactHost: ReactHost
60- get() = getDefaultReactHost(applicationContext, reactNativeHost)
67+ // Build the bridgeless ReactHost ourselves (instead of DefaultReactHost.getDefaultReactHost)
68+ // so we can supply a *dynamic* JSBundleLoader. reactHost.reload() destroys and recreates the
69+ // React instance, re-invoking this loader's loadScript() on every reload. By resolving
70+ // getJSBundleFile() inside loadScript() each time, a freshly-deployed OTA bundle is picked up
71+ // automatically — without this the loader is fixed at construction time and the app loops:
72+ // download -> deploy -> reload -> same old bundle. `by lazy` keeps it a single host instance.
73+ @OptIn(UnstableReactNativeAPI ::class )
74+ override val reactHost: ReactHost by lazy {
75+ val dynamicBundleLoader = object : JSBundleLoader () {
76+ override fun loadScript (delegate : JSBundleLoaderDelegate ): String {
77+ val bundle = jsBundleFile
78+ if (bundle != null ) {
79+ if (bundle.startsWith(" assets://" )) {
80+ delegate.loadScriptFromAssets(assets, bundle, true )
81+ } else {
82+ delegate.loadScriptFromFile(bundle, bundle, false )
83+ }
84+ return bundle
85+ }
86+ val defaultBundle = " assets://index.android.bundle"
87+ delegate.loadScriptFromAssets(assets, defaultBundle, true )
88+ return defaultBundle
89+ }
90+ }
91+
92+ val hostPackages: MutableList <ReactPackage > = ArrayList (this @MendixReactApplication.packages)
93+ applyInternalPackageAugmentations(hostPackages)
94+
95+ val delegate = DefaultReactHostDelegate (
96+ jsMainModulePath = " index" ,
97+ jsBundleLoader = dynamicBundleLoader,
98+ reactPackages = hostPackages,
99+ jsRuntimeFactory = HermesInstance (),
100+ turboModuleManagerDelegateBuilder = DefaultTurboModuleManagerDelegate .Builder (),
101+ )
102+ val componentFactory = ComponentFactory ()
103+ DefaultComponentsRegistry .register(componentFactory)
104+ ReactHostImpl (
105+ applicationContext,
106+ delegate,
107+ componentFactory,
108+ true /* allowPackagerServerAccess */ ,
109+ useDeveloperSupport,
110+ )
111+ }
61112
62113 /* *
63114 * Apply internal augmentations to packages (e.g., attach presenters) without instantiating
0 commit comments