Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,16 @@ import android.app.Application
import com.facebook.react.ReactHost
import com.facebook.react.ReactNativeHost
import com.facebook.react.ReactPackage
import com.facebook.react.bridge.JSBundleLoader
import com.facebook.react.bridge.JSBundleLoaderDelegate
import com.facebook.react.common.annotations.UnstableReactNativeAPI
import com.facebook.react.defaults.DefaultComponentsRegistry
import com.facebook.react.defaults.DefaultReactHostDelegate
import com.facebook.react.defaults.DefaultTurboModuleManagerDelegate
import com.facebook.react.devsupport.interfaces.RedBoxHandler
import com.facebook.react.fabric.ComponentFactory
import com.facebook.react.runtime.ReactHostImpl
import com.facebook.react.runtime.hermes.HermesInstance
import com.facebook.react.soloader.OpenSourceMergedSoMapping
import com.facebook.soloader.SoLoader
import com.mendix.mendixnative.error.ErrorHandler
Expand All @@ -16,7 +25,6 @@ import com.mendix.mendixnative.react.splash.MendixSplashScreenPresenter
import com.mendixnative.MendixNativePackage
import java.util.*
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load
import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost

import com.facebook.react.defaults.DefaultReactNativeHost

Expand Down Expand Up @@ -56,8 +64,51 @@ abstract class MendixReactApplication : Application(), MendixApplication, ErrorH
override val isHermesEnabled: Boolean = true
}

override val reactHost: ReactHost
get() = getDefaultReactHost(applicationContext, reactNativeHost)
// Build the bridgeless ReactHost ourselves (instead of DefaultReactHost.getDefaultReactHost)
// so we can supply a *dynamic* JSBundleLoader. reactHost.reload() destroys and recreates the
// React instance, re-invoking this loader's loadScript() on every reload. By resolving
// getJSBundleFile() inside loadScript() each time, a freshly-deployed OTA bundle is picked up
// automatically — without this the loader is fixed at construction time and the app loops:
// download -> deploy -> reload -> same old bundle. `by lazy` keeps it a single host instance.
@OptIn(UnstableReactNativeAPI::class)
override val reactHost: ReactHost by lazy {
val dynamicBundleLoader = object : JSBundleLoader() {
override fun loadScript(delegate: JSBundleLoaderDelegate): String {
val bundle = jsBundleFile
if (bundle != null) {
if (bundle.startsWith("assets://")) {
delegate.loadScriptFromAssets(assets, bundle, true)
} else {
delegate.loadScriptFromFile(bundle, bundle, false)
}
return bundle
}
val defaultBundle = "assets://index.android.bundle"
delegate.loadScriptFromAssets(assets, defaultBundle, true)
return defaultBundle
}
}

val hostPackages: MutableList<ReactPackage> = ArrayList(this@MendixReactApplication.packages)
applyInternalPackageAugmentations(hostPackages)

val delegate = DefaultReactHostDelegate(
jsMainModulePath = "index",
jsBundleLoader = dynamicBundleLoader,
reactPackages = hostPackages,
jsRuntimeFactory = HermesInstance(),
turboModuleManagerDelegateBuilder = DefaultTurboModuleManagerDelegate.Builder(),
)
val componentFactory = ComponentFactory()
DefaultComponentsRegistry.register(componentFactory)
ReactHostImpl(
applicationContext,
delegate,
componentFactory,
true /* allowPackagerServerAccess */,
useDeveloperSupport,
)
}

/**
* Apply internal augmentations to packages (e.g., attach presenters) without instantiating
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,8 @@ import android.os.Handler
import android.os.Looper
import com.facebook.common.logging.FLog
import com.facebook.react.ReactApplication
import com.facebook.react.bridge.JSBundleLoader
import com.facebook.react.bridge.ReactApplicationContext
import com.mendix.mendixnative.MendixApplication
import com.mendix.mendixnative.activity.LaunchScreenHandler
import com.mendix.mendixnative.util.ReflectionUtils
import com.op.sqlite.OPSQLiteModule

class NativeReloadHandler(val context: ReactApplicationContext) {

Expand All @@ -24,14 +20,18 @@ class NativeReloadHandler(val context: ReactApplicationContext) {
javaClass,
"Activity does not implement LaunchScreenHandler, skipping showing launch screen"
)
handleJSBundleLoading()
reloadWithoutState()
}

fun exitApp() {
context.currentActivity?.finishAffinity()
}

// In the New Architecture (Bridgeless), reactHost.reload() destroys and recreates the
// React instance, which re-invokes the JSBundleLoader provided to ReactHostImpl at
// construction time. MendixReactApplication supplies a *dynamic* JSBundleLoader whose
// loadScript() calls MendixReactApplication.getJSBundleFile() on every reload, so OTA
// bundle changes are picked up automatically — no manual bundle swapping is needed.
private fun reloadWithoutState() {
val reactHost = (context.applicationContext as? ReactApplication)?.reactHost
postOnMainThread {
Expand All @@ -48,35 +48,4 @@ class NativeReloadHandler(val context: ReactApplicationContext) {
cb.invoke()
}
}

private fun handleJSBundleLoading() {
val bundle = (context.applicationContext as MendixApplication).jsBundleFile
val instanceManager =
(context.applicationContext as ReactApplication).reactNativeHost.reactInstanceManager

val latestJSBundleLoader = if (bundle != null) {
getAssetLoader(bundle)
} else {
getAssetLoader("assets://index.android.bundle")
}

ReflectionUtils.setField(instanceManager, "mBundleLoader", latestJSBundleLoader)
ReflectionUtils.setField(
instanceManager,
"mUseDeveloperSupport",
(context.applicationContext as MendixApplication).useDeveloperSupport
)
}

private fun getAssetLoader(bundle: String): JSBundleLoader? {
return when {
bundle.startsWith("assets://") -> JSBundleLoader.createAssetLoader(
context,
bundle,
false
)

else -> JSBundleLoader.createFileLoader(bundle)
}
}
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "mendix-native",
"version": "0.3.0",
"version": "0.3.2",
Comment thread
YogendraShelke marked this conversation as resolved.
"description": "Mendix native mobile package",
"main": "./lib/module/index.js",
"types": "./lib/typescript/src/index.d.ts",
Expand Down
Loading