Commit b0abdcd
Android: Add
Summary:
Following the [RFC](react-native-community/discussions-and-proposals#933), this PR adds new `setBundleSource` methods to `ReactHost` for modifying bundle URL at runtime. The first one with signature:
```Kotlin
public fun setBundleSource(debugServerHost: String, moduleName: String, queryBuilder: (Map<String, String>) -> Map<String, String> = { it })
```
takes debugServerHost (set in packager connection settings), moduleName (set in DevSupportManager's jsAppBundleName), and queryBuilder (set in packager connection settings). Before updating settings, the packager connection is closed to reset the packager client, which will be newly created during reload with updated configuration.
The second one for loading bundle from the file takes single `filePath` argument:
```Kotlin
public fun setBundleSource(filePath: String)
```
It sets `customBundleFilePath` in `DevSupportManager` which has priority over other methods of loading the bundle in `jsBundleLoader` and reloads `ReactHost`.
## Changelog:
[ANDROID][ADDED] - added new `setBundleSource` method to `ReactHost` for changing bundle URL at runtime.
Test Plan:
Started with running two Metro instances on ports `8081` and `8082` (first with white background, second with blue). Created a native button that toggles `debugServerHost` port and invokes `setBundleSource`.
https://github.com/user-attachments/assets/7afe2cbc-6fef-44bc-930c-e9f9c4edd2bd
For setting bundle file path, generated JS bundle with different background comparing to the one serving by Metro. Moved file to the `app/files` directory in android emulator and configured native button to invoke a `setBundleSource(filePath)`.
https://github.com/user-attachments/assets/5e59d7b7-c6ae-475c-94e3-50d4ac69cf24
<details>
<summary>code:</summary>
Changing debug server host:
`RNTesterActivity.kt`:
```Kotlin
package com.facebook.react.uiapp
import android.content.res.Configuration
import android.graphics.Color
import android.os.Bundle
import android.view.View
import android.widget.Button
import android.widget.FrameLayout
import androidx.core.graphics.drawable.toDrawable
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import com.facebook.common.logging.FLog
import com.facebook.react.FBRNTesterEndToEndHelper
import com.facebook.react.ReactActivity
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled
import com.facebook.react.defaults.DefaultReactActivityDelegate
import java.io.FileDescriptor
import java.io.PrintWriter
internal class RNTesterActivity : ReactActivity() {
private var activePort = "8081"
class RNTesterActivityDelegate(val activity: ReactActivity, mainComponentName: String) :
DefaultReactActivityDelegate(activity, mainComponentName, fabricEnabled) {
private val PARAM_ROUTE = "route"
private lateinit var initialProps: Bundle
override fun onCreate(savedInstanceState: Bundle?) {
// Get remote param before calling super which uses it
val bundle = activity.intent?.extras
if (bundle != null && bundle.containsKey(PARAM_ROUTE)) {
val routeUri = "rntester://example/${bundle.getString(PARAM_ROUTE)}Example"
initialProps = Bundle().apply { putString("exampleFromAppetizeParams", routeUri) }
}
FBRNTesterEndToEndHelper.onCreate(activity.application)
super.onCreate(savedInstanceState)
}
override fun getLaunchOptions() =
if (this::initialProps.isInitialized) initialProps else Bundle()
}
private fun getButtonText(): String {
return "Port: $activePort"
}
private fun setupPortButton(onClick: () -> Unit) {
val portButton = Button(this).apply {
text = getButtonText()
setBackgroundColor(Color.rgb(0, 123, 255)) // Blue background
setTextColor(Color.WHITE)
setPadding(32, 16, 32, 16)
textSize = 16f
elevation = 8f
}
// Get the root view and add button to it
val rootView = this.findViewById<FrameLayout>(android.R.id.content)
val layoutParams = FrameLayout.LayoutParams(
FrameLayout.LayoutParams.WRAP_CONTENT,
FrameLayout.LayoutParams.WRAP_CONTENT
).apply {
gravity = android.view.Gravity.TOP or android.view.Gravity.CENTER_HORIZONTAL
topMargin = 200 // 50dp from top
}
rootView.addView(portButton, layoutParams)
portButton.setOnClickListener {
onClick()
portButton.text = getButtonText()
}
}
// set background color so it will show below transparent system bars on forced edge-to-edge
private fun maybeUpdateBackgroundColor() {
val isDarkMode =
resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK ==
Configuration.UI_MODE_NIGHT_YES
val color =
if (isDarkMode) {
Color.rgb(11, 6, 0)
} else {
Color.rgb(243, 248, 255)
}
window?.setBackgroundDrawable(color.toDrawable())
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
fullyDrawnReporter.addReporter()
maybeUpdateBackgroundColor()
reactDelegate?.reactHost?.let {
setupPortButton {
activePort = if (activePort == "8081") "8082" else "8081"
reactHost.setBundleSource("10.0.2.2:$activePort", "js/RNTesterApp.android")
// reactHost.setBundleSource("/data/user/0/com.facebook.react.uiapp/files/android.bundle")
}
}
// register insets listener to update margins on the ReactRootView to avoid overlap w/ system
// bars
reactDelegate?.reactRootView?.let { rootView ->
val insetsType: Int =
WindowInsetsCompat.Type.systemBars() or WindowInsetsCompat.Type.displayCutout()
val windowInsetsListener = { view: View, windowInsets: WindowInsetsCompat ->
val insets = windowInsets.getInsets(insetsType)
(view.layoutParams as FrameLayout.LayoutParams).apply {
setMargins(insets.left, insets.top, insets.right, insets.bottom)
}
WindowInsetsCompat.CONSUMED
}
ViewCompat.setOnApplyWindowInsetsListener(rootView, windowInsetsListener)
}
}
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
// update background color on UI mode change
maybeUpdateBackgroundColor()
}
override fun createReactActivityDelegate() = RNTesterActivityDelegate(this, mainComponentName)
override fun getMainComponentName() = "RNTesterApp"
override fun dump(
prefix: String,
fd: FileDescriptor?,
writer: PrintWriter,
args: Array<String>?,
) {
FBRNTesterEndToEndHelper.maybeDump(prefix, writer, args)
}
}
```
</detail>
Differential Revision: D84713639
Pulled By: coadosetBundleSource method to ReactHost for changing bundle URL at runtime (facebook#54139)1 parent 2d98055 commit b0abdcd
File tree
7 files changed
+98
-17
lines changed- packages/react-native/ReactAndroid
- api
- src/main/java/com/facebook/react
- devsupport
- interfaces
- packagerconnection
- runtime
7 files changed
+98
-17
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
239 | 239 | | |
240 | 240 | | |
241 | 241 | | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
242 | 245 | | |
243 | 246 | | |
244 | 247 | | |
| |||
1943 | 1946 | | |
1944 | 1947 | | |
1945 | 1948 | | |
| 1949 | + | |
1946 | 1950 | | |
1947 | 1951 | | |
1948 | 1952 | | |
| |||
1977 | 1981 | | |
1978 | 1982 | | |
1979 | 1983 | | |
| 1984 | + | |
1980 | 1985 | | |
1981 | 1986 | | |
1982 | 1987 | | |
1983 | 1988 | | |
1984 | 1989 | | |
| 1990 | + | |
1985 | 1991 | | |
1986 | 1992 | | |
1987 | 1993 | | |
| |||
2151 | 2157 | | |
2152 | 2158 | | |
2153 | 2159 | | |
| 2160 | + | |
2154 | 2161 | | |
2155 | 2162 | | |
2156 | 2163 | | |
| |||
2180 | 2187 | | |
2181 | 2188 | | |
2182 | 2189 | | |
| 2190 | + | |
2183 | 2191 | | |
2184 | 2192 | | |
2185 | 2193 | | |
| |||
3021 | 3029 | | |
3022 | 3030 | | |
3023 | 3031 | | |
| 3032 | + | |
| 3033 | + | |
3024 | 3034 | | |
3025 | 3035 | | |
3026 | 3036 | | |
| |||
3099 | 3109 | | |
3100 | 3110 | | |
3101 | 3111 | | |
| 3112 | + | |
| 3113 | + | |
3102 | 3114 | | |
3103 | 3115 | | |
3104 | 3116 | | |
| |||
Lines changed: 17 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
193 | 193 | | |
194 | 194 | | |
195 | 195 | | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
196 | 213 | | |
Lines changed: 5 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
280 | 280 | | |
281 | 281 | | |
282 | 282 | | |
283 | | - | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
284 | 288 | | |
285 | 289 | | |
286 | 290 | | |
| |||
Lines changed: 7 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
85 | 85 | | |
86 | 86 | | |
87 | 87 | | |
88 | | - | |
| 88 | + | |
89 | 89 | | |
90 | 90 | | |
91 | 91 | | |
| |||
148 | 148 | | |
149 | 149 | | |
150 | 150 | | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
151 | 157 | | |
152 | 158 | | |
153 | 159 | | |
| |||
Lines changed: 4 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
48 | 48 | | |
49 | 49 | | |
50 | 50 | | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
51 | 55 | | |
52 | 56 | | |
53 | 57 | | |
| |||
Lines changed: 17 additions & 15 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
7 | | - | |
8 | | - | |
9 | | - | |
10 | 7 | | |
11 | 8 | | |
12 | 9 | | |
13 | | - | |
14 | | - | |
15 | 10 | | |
16 | 11 | | |
17 | 12 | | |
18 | 13 | | |
19 | | - | |
20 | | - | |
21 | 14 | | |
22 | 15 | | |
| 16 | + | |
| 17 | + | |
23 | 18 | | |
24 | 19 | | |
25 | 20 | | |
26 | | - | |
| 21 | + | |
27 | 22 | | |
28 | | - | |
29 | | - | |
30 | | - | |
| 23 | + | |
| 24 | + | |
31 | 25 | | |
32 | 26 | | |
33 | 27 | | |
| |||
36 | 30 | | |
37 | 31 | | |
38 | 32 | | |
| 33 | + | |
| 34 | + | |
39 | 35 | | |
40 | 36 | | |
41 | 37 | | |
42 | 38 | | |
43 | | - | |
| 39 | + | |
44 | 40 | | |
45 | | - | |
| 41 | + | |
46 | 42 | | |
47 | 43 | | |
48 | 44 | | |
49 | 45 | | |
50 | | - | |
| 46 | + | |
51 | 47 | | |
52 | 48 | | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
53 | 56 | | |
54 | 57 | | |
55 | 58 | | |
| |||
59 | 62 | | |
60 | 63 | | |
61 | 64 | | |
62 | | - | |
63 | 65 | | |
64 | 66 | | |
Lines changed: 36 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
74 | 74 | | |
75 | 75 | | |
76 | 76 | | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
77 | 80 | | |
78 | 81 | | |
79 | 82 | | |
| |||
650 | 653 | | |
651 | 654 | | |
652 | 655 | | |
| 656 | + | |
| 657 | + | |
| 658 | + | |
| 659 | + | |
| 660 | + | |
| 661 | + | |
| 662 | + | |
| 663 | + | |
| 664 | + | |
| 665 | + | |
| 666 | + | |
| 667 | + | |
| 668 | + | |
| 669 | + | |
| 670 | + | |
| 671 | + | |
| 672 | + | |
| 673 | + | |
| 674 | + | |
| 675 | + | |
| 676 | + | |
| 677 | + | |
| 678 | + | |
653 | 679 | | |
654 | 680 | | |
655 | 681 | | |
| |||
1064 | 1090 | | |
1065 | 1091 | | |
1066 | 1092 | | |
| 1093 | + | |
| 1094 | + | |
| 1095 | + | |
| 1096 | + | |
| 1097 | + | |
| 1098 | + | |
| 1099 | + | |
| 1100 | + | |
| 1101 | + | |
| 1102 | + | |
1067 | 1103 | | |
1068 | 1104 | | |
1069 | 1105 | | |
| |||
0 commit comments