Skip to content

Commit 874332b

Browse files
fix: make sure native libs are loaded for RN >= 0.80 (#315)
* fix: make sure native libs are loaded for RN >= 0.80 cause: loadNativeLibs() in ReactNativeBrownfield.kt is a no-op for RN >= 0.80. All ReactNativeHostManager templates call loadReactNative(application) BEFORE ReactNativeBrownfield.initialize(), so when done through the recommended path the libs load. But loadNativeLibs() — called inside every initialize() overload — silently skips for RN >= 0.80. Any consumer using ReactNativeBrownfield.initialize() directly — with a custom ReactHost, custom packages list, or custom options — skipped native lib loading entirely. Without JNI_OnLoad firing, registerComponentDescriptorsFromEntryPoint and the DefaultTurboModuleManagerDelegate module providers were never assigned, leading to the SIGSEGV during Fabric initialization. ddc011c — moved SoLoader.init() from preloadReactNative() into initialize(application, rnHost, ...). Before this, SoLoader.init() was called inside preloadReactNative after creating the React context. It was consolidated into the initialize entry point. 9908b68 — added the RN_THRESHOLD_VERSION = "0.80.0" gate and removed SoLoader.init() + load() for RN ≥ 0.80, leaving those calls only for < 0.80. ReactNativeBrownfield.initialize() itself had no fallback for the RN ≥ 0.80 case. If anything bypasses ReactNativeHostManager — a custom ReactHost, a consumer calling initialize() directly, or the generated ReactNativeApplicationEntryPoint being unavailable — native libs are never loaded. That's the bug this fix addresses. * docs: add changeset * fix: address compilation issue * fix: drop support for RN < 0.80 * fix: get rid of redundant (now) PG config
1 parent a4de8d2 commit 874332b

6 files changed

Lines changed: 15 additions & 22 deletions

File tree

.changeset/early-rice-fly.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@callstack/react-native-brownfield': patch
3+
---
4+
5+
fix: make sure native libs are loaded for RN >= 0.80

apps/RNApp/android/BrownfieldLib/consumer-rules.pro

Whitespace-only changes.

apps/RNApp/android/BrownfieldLib/src/main/java/com/rnapp/brownfieldlib/ReactNativeHostManager.kt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,9 @@ import android.app.Application
44
import com.callstack.reactnativebrownfield.OnJSBundleLoaded
55
import com.callstack.reactnativebrownfield.ReactNativeBrownfield
66
import com.facebook.react.PackageList
7-
import com.facebook.react.ReactNativeApplicationEntryPoint.loadReactNative
87

98
object ReactNativeHostManager {
109
fun initialize(application: Application, onJSBundleLoaded: OnJSBundleLoaded? = null) {
11-
loadReactNative(application)
12-
1310
val packageList = PackageList(application).packages
1411
ReactNativeBrownfield.initialize(application, packageList, onJSBundleLoaded)
1512
}

packages/react-native-brownfield/android/src/main/java/com/callstack/reactnativebrownfield/ReactNativeBrownfield.kt

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import androidx.activity.OnBackPressedCallback
77
import androidx.fragment.app.FragmentActivity
88
import androidx.lifecycle.DefaultLifecycleObserver
99
import androidx.lifecycle.LifecycleOwner
10-
import com.callstack.reactnativebrownfield.utils.VersionUtils
1110
import com.facebook.react.ReactHost
1211
import com.facebook.react.ReactInstanceEventListener
1312
import com.facebook.react.ReactPackage
@@ -28,33 +27,29 @@ fun interface OnMessageListener {
2827
fun onMessage(message: String)
2928
}
3029

31-
/**
32-
* The threshold RN version based on which we decide whether to
33-
* load JNI libs or not. We only load JNI libs on version less
34-
* than this.
35-
*/
36-
private const val RN_THRESHOLD_VERSION = "0.80.0"
37-
3830
class ReactNativeBrownfield private constructor(val reactHost: ReactHost) {
3931
private val messageListeners = CopyOnWriteArrayList<OnMessageListener>()
4032

4133
companion object {
4234
private lateinit var instance: ReactNativeBrownfield
4335
private val initialized = AtomicBoolean()
36+
private val nativeLibsLoaded = AtomicBoolean()
4437
private const val LOG_TAG = "ReactNativeBrownfield"
4538

4639
@JvmStatic
4740
val shared: ReactNativeBrownfield get() = instance
4841

4942
private fun loadNativeLibs(application: Application) {
50-
val rnVersion = BuildConfig.RN_VERSION
51-
52-
if (VersionUtils.isVersionLessThan(rnVersion, RN_THRESHOLD_VERSION)) {
53-
SoLoader.init(application.applicationContext, OpenSourceMergedSoMapping)
54-
load()
43+
if (!nativeLibsLoaded.getAndSet(true)) {
44+
loadNativeLibsInternal(application)
5545
}
5646
}
5747

48+
private fun loadNativeLibsInternal(application: Application) {
49+
SoLoader.init(application.applicationContext, OpenSourceMergedSoMapping)
50+
load()
51+
}
52+
5853
@JvmStatic
5954
@JvmOverloads
6055
fun initialize(
@@ -79,6 +74,8 @@ class ReactNativeBrownfield private constructor(val reactHost: ReactHost) {
7974
options: HashMap<String, Any>,
8075
onJSBundleLoaded: OnJSBundleLoaded? = null
8176
) {
77+
loadNativeLibs(application)
78+
8279
val reactHost: ReactHost by lazy {
8380
getDefaultReactHost(
8481
context = application,

packages/react-native-brownfield/src/expo-config-plugin/template/android/ReactNativeHostManager.post55.kt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,11 @@ import com.callstack.reactnativebrownfield.OnJSBundleLoaded
66
import com.callstack.reactnativebrownfield.ReactNativeBrownfield
77
import com.facebook.react.PackageList
88
import com.facebook.react.ReactHost
9-
import com.facebook.react.ReactNativeApplicationEntryPoint.loadReactNative
109
import expo.modules.ApplicationLifecycleDispatcher
1110
import expo.modules.ExpoReactHostFactory
1211

1312
object ReactNativeHostManager {
1413
fun initialize(application: Application, onJSBundleLoaded: OnJSBundleLoaded? = null) {
15-
loadReactNative(application)
16-
1714
ApplicationLifecycleDispatcher.onApplicationCreate(application)
1815

1916
val reactHost: ReactHost by lazy {

packages/react-native-brownfield/src/expo-config-plugin/template/android/ReactNativeHostManager.pre55.kt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import com.callstack.reactnativebrownfield.OnJSBundleLoaded
66
import com.callstack.reactnativebrownfield.ReactNativeBrownfield
77
import com.facebook.react.PackageList
88
import com.facebook.react.ReactHost
9-
import com.facebook.react.ReactNativeApplicationEntryPoint.loadReactNative
109
import com.facebook.react.ReactPackage
1110
import com.facebook.react.defaults.DefaultReactNativeHost
1211
import expo.modules.ApplicationLifecycleDispatcher
@@ -15,8 +14,6 @@ import expo.modules.ReactNativeHostWrapper
1514

1615
object ReactNativeHostManager {
1716
fun initialize(application: Application, onJSBundleLoaded: OnJSBundleLoaded? = null) {
18-
loadReactNative(application)
19-
2017
ApplicationLifecycleDispatcher.onApplicationCreate(application)
2118

2219
val reactNativeHost = ReactNativeHostWrapper(

0 commit comments

Comments
 (0)