Skip to content
Open
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
5 changes: 5 additions & 0 deletions .changeset/early-rice-fly.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@callstack/react-native-brownfield': patch
---

fix: make sure native libs are loaded for RN >= 0.80
1 change: 1 addition & 0 deletions apps/RNApp/android/BrownfieldLib/consumer-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-keep class com.facebook.react.ReactNativeApplicationEntryPoint { *; }
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,9 @@ import android.app.Application
import com.callstack.reactnativebrownfield.OnJSBundleLoaded
import com.callstack.reactnativebrownfield.ReactNativeBrownfield
import com.facebook.react.PackageList
import com.facebook.react.ReactNativeApplicationEntryPoint.loadReactNative

object ReactNativeHostManager {
fun initialize(application: Application, onJSBundleLoaded: OnJSBundleLoaded? = null) {
loadReactNative(application)

val packageList = PackageList(application).packages
ReactNativeBrownfield.initialize(application, packageList, onJSBundleLoaded)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,41 @@ class ReactNativeBrownfield private constructor(val reactHost: ReactHost) {
companion object {
private lateinit var instance: ReactNativeBrownfield
private val initialized = AtomicBoolean()
private val nativeLibsLoaded = AtomicBoolean()
private const val LOG_TAG = "ReactNativeBrownfield"

@JvmStatic
val shared: ReactNativeBrownfield get() = instance

private fun loadNativeLibs(application: Application) {
if (!nativeLibsLoaded.getAndSet(true)) {
loadNativeLibsInternal(application)
}
}

private fun loadNativeLibsInternal(application: Application) {
val rnVersion = BuildConfig.RN_VERSION

if (VersionUtils.isVersionLessThan(rnVersion, RN_THRESHOLD_VERSION)) {
SoLoader.init(application.applicationContext, OpenSourceMergedSoMapping)
load()
} else {
try {
val reactNativeApplicationEntryPointClazz =
Class.forName("com.facebook.react.ReactNativeApplicationEntryPoint")
val loadReactNativeMethod = reactNativeApplicationEntryPointClazz.getMethod(
"loadReactNative",
android.content.Context::class.java
)
loadReactNativeMethod.invoke(null, application.applicationContext)
Comment on lines +65 to +70
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we discussed, let's try to check which versions of RN expose this API and instead of reflection, try checking the version

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also think we should drop RN <=80 support now, no point in maintaining a version outside of release support window.

Copy link
Copy Markdown
Collaborator

@artus9033 artus9033 May 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, if this is only for <= 0.80, I think we can drop it. Our compat matrix states >=0.83 for Brownfield v3. But the original issue mentioned RN 0.83.2, which is in our scope. CC @marcinszalski-callstack

} catch (e: ClassNotFoundException) {
throw RuntimeException(
"ReactNativeApplicationEntryPoint not found. Ensure the brownfield AAR " +
"consumer-rules.pro is applied and ReactNativeApplicationEntryPoint is " +
"not stripped by R8.",
e
)
}
}
}

Expand Down Expand Up @@ -79,6 +103,8 @@ class ReactNativeBrownfield private constructor(val reactHost: ReactHost) {
options: HashMap<String, Any>,
onJSBundleLoaded: OnJSBundleLoaded? = null
) {
loadNativeLibs(application)

val reactHost: ReactHost by lazy {
getDefaultReactHost(
context = application,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,11 @@ import com.callstack.reactnativebrownfield.OnJSBundleLoaded
import com.callstack.reactnativebrownfield.ReactNativeBrownfield
import com.facebook.react.PackageList
import com.facebook.react.ReactHost
import com.facebook.react.ReactNativeApplicationEntryPoint.loadReactNative
import expo.modules.ApplicationLifecycleDispatcher
import expo.modules.ExpoReactHostFactory

object ReactNativeHostManager {
fun initialize(application: Application, onJSBundleLoaded: OnJSBundleLoaded? = null) {
loadReactNative(application)

ApplicationLifecycleDispatcher.onApplicationCreate(application)

val reactHost: ReactHost by lazy {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import com.callstack.reactnativebrownfield.OnJSBundleLoaded
import com.callstack.reactnativebrownfield.ReactNativeBrownfield
import com.facebook.react.PackageList
import com.facebook.react.ReactHost
import com.facebook.react.ReactNativeApplicationEntryPoint.loadReactNative
import com.facebook.react.ReactPackage
import com.facebook.react.defaults.DefaultReactNativeHost
import expo.modules.ApplicationLifecycleDispatcher
Expand All @@ -15,8 +14,6 @@ import expo.modules.ReactNativeHostWrapper

object ReactNativeHostManager {
fun initialize(application: Application, onJSBundleLoaded: OnJSBundleLoaded? = null) {
loadReactNative(application)

ApplicationLifecycleDispatcher.onApplicationCreate(application)

val reactNativeHost = ReactNativeHostWrapper(
Expand Down
Loading