Skip to content

Commit 0e7ba90

Browse files
RSNarafacebook-github-bot
authored andcommitted
Make redboxes resilient to react native preloading (#47391)
Summary: Pull Request resolved: #47391 React Native can preload before the activity is available. Preloading will execute the js bundle. If the js bundle throws an error, it'll try to render a redbox. If the activity isn't available, and hasn't been set on the react instance yet, the redbox will just render nothing. ## Changes In this diff, just re-try displaying the redbox after the application sets the activity on the react instance (i.e: calls onHostResume(activity)). Changelog: [Android][Breaking] - Rename DevSupportManagerBase.getCurrentContext() -> getCurrentReactContext() Reviewed By: mdvacca Differential Revision: D65352596 fbshipit-source-id: 7750f6ca493fc50405119958e0f2908fc24f1cb4
1 parent 5a6a42c commit 0e7ba90

File tree

5 files changed

+39
-4
lines changed

5 files changed

+39
-4
lines changed

packages/react-native/ReactAndroid/api/ReactAndroid.api

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2161,7 +2161,7 @@ public abstract class com/facebook/react/devsupport/DevSupportManagerBase : com/
21612161
public fun fetchSplitBundleAndCreateBundleLoader (Ljava/lang/String;Lcom/facebook/react/devsupport/DevSupportManagerBase$CallbackWithBundleLoader;)V
21622162
protected fun getApplicationContext ()Landroid/content/Context;
21632163
public fun getCurrentActivity ()Landroid/app/Activity;
2164-
protected fun getCurrentReactContext ()Lcom/facebook/react/bridge/ReactContext;
2164+
public fun getCurrentReactContext ()Lcom/facebook/react/bridge/ReactContext;
21652165
public fun getDevLoadingViewManager ()Lcom/facebook/react/devsupport/interfaces/DevLoadingViewManager;
21662166
public fun getDevServerHelper ()Lcom/facebook/react/devsupport/DevServerHelper;
21672167
public fun getDevSettings ()Lcom/facebook/react/modules/debug/interfaces/DeveloperSettings;
@@ -2334,6 +2334,7 @@ public class com/facebook/react/devsupport/ReleaseDevSupportManager : com/facebo
23342334
public fun destroyRootView (Landroid/view/View;)V
23352335
public fun downloadBundleResourceFromUrlSync (Ljava/lang/String;Ljava/io/File;)Ljava/io/File;
23362336
public fun getCurrentActivity ()Landroid/app/Activity;
2337+
public fun getCurrentReactContext ()Lcom/facebook/react/bridge/ReactContext;
23372338
public fun getDevSettings ()Lcom/facebook/react/modules/debug/interfaces/DeveloperSettings;
23382339
public fun getDevSupportEnabled ()Z
23392340
public fun getDownloadedJSBundleFile ()Ljava/lang/String;
@@ -2470,6 +2471,7 @@ public abstract interface class com/facebook/react/devsupport/interfaces/DevSupp
24702471
public abstract fun destroyRootView (Landroid/view/View;)V
24712472
public abstract fun downloadBundleResourceFromUrlSync (Ljava/lang/String;Ljava/io/File;)Ljava/io/File;
24722473
public abstract fun getCurrentActivity ()Landroid/app/Activity;
2474+
public abstract fun getCurrentReactContext ()Lcom/facebook/react/bridge/ReactContext;
24732475
public abstract fun getDevSettings ()Lcom/facebook/react/modules/debug/interfaces/DeveloperSettings;
24742476
public abstract fun getDevSupportEnabled ()Z
24752477
public abstract fun getDownloadedJSBundleFile ()Ljava/lang/String;

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerBase.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -707,7 +707,7 @@ public void reloadSettings() {
707707
}
708708
}
709709

710-
protected @Nullable ReactContext getCurrentReactContext() {
710+
public @Nullable ReactContext getCurrentReactContext() {
711711
return mCurrentReactContext;
712712
}
713713

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/RedBoxDialogSurfaceDelegate.java

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import androidx.core.view.WindowInsetsCompat;
2222
import com.facebook.common.logging.FLog;
2323
import com.facebook.react.R;
24+
import com.facebook.react.bridge.LifecycleEventListener;
25+
import com.facebook.react.bridge.ReactContext;
2426
import com.facebook.react.common.ReactConstants;
2527
import com.facebook.react.common.SurfaceDelegate;
2628
import com.facebook.react.devsupport.interfaces.DevSupportManager;
@@ -55,7 +57,7 @@ public void createContentView(String appKey) {
5557
FLog.e(
5658
ReactConstants.TAG,
5759
"Unable to launch redbox because react activity "
58-
+ "is not available, here is the error that redbox would've displayed: "
60+
+ "are not available, here is the error that redbox would've displayed: "
5961
+ (message != null ? message : "N/A"));
6062
return;
6163
}
@@ -82,9 +84,19 @@ public void show() {
8284
@Nullable String message = mDevSupportManager.getLastErrorTitle();
8385
Activity context = mDevSupportManager.getCurrentActivity();
8486
if (context == null || context.isFinishing()) {
87+
final @Nullable ReactContext reactContext = mDevSupportManager.getCurrentReactContext();
88+
if (reactContext != null) {
89+
/**
90+
* If the activity isn't available, try again after the next onHostResume(). onHostResume()
91+
* is when the activity gets attached to the react native.
92+
*/
93+
runAfterHostResume(reactContext, this::show);
94+
return;
95+
}
96+
8597
FLog.e(
8698
ReactConstants.TAG,
87-
"Unable to launch redbox because react activity "
99+
"Unable to launch redbox because react activity and react context "
88100
+ "is not available, here is the error that redbox would've displayed: "
89101
+ (message != null ? message : "N/A"));
90102
return;
@@ -140,6 +152,23 @@ protected void onCreate(Bundle savedInstanceState) {
140152
mDialog.show();
141153
}
142154

155+
private static void runAfterHostResume(ReactContext reactContext, Runnable runnable) {
156+
reactContext.addLifecycleEventListener(
157+
new LifecycleEventListener() {
158+
@Override
159+
public void onHostResume() {
160+
runnable.run();
161+
reactContext.removeLifecycleEventListener(this);
162+
}
163+
164+
@Override
165+
public void onHostPause() {}
166+
167+
@Override
168+
public void onHostDestroy() {}
169+
});
170+
}
171+
143172
@Override
144173
public void hide() {
145174
// dismiss redbox if exists

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/ReleaseDevSupportManager.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,9 @@ public open class ReleaseDevSupportManager : DevSupportManager {
147147
override public val currentActivity: Activity?
148148
get() = null
149149

150+
override public val currentReactContext: ReactContext?
151+
get() = null
152+
150153
override public fun createSurfaceDelegate(moduleName: String?): SurfaceDelegate? = null
151154

152155
override public fun openDebugger(): Unit = Unit

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/devsupport/interfaces/DevSupportManager.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ public interface DevSupportManager : JSExceptionHandler {
3535
public val lastErrorType: ErrorType?
3636
public val lastErrorCookie: Int
3737
public val currentActivity: Activity?
38+
public val currentReactContext: ReactContext?
3839

3940
public var devSupportEnabled: Boolean
4041

0 commit comments

Comments
 (0)