Skip to content

Commit

Permalink
Make redboxes resilient to react native preloading (facebook#47391)
Browse files Browse the repository at this point in the history
Summary:
Pull Request resolved: facebook#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
  • Loading branch information
RSNara authored and facebook-github-bot committed Nov 5, 2024
1 parent 5a6a42c commit 0e7ba90
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 4 deletions.
4 changes: 3 additions & 1 deletion packages/react-native/ReactAndroid/api/ReactAndroid.api
Original file line number Diff line number Diff line change
Expand Up @@ -2161,7 +2161,7 @@ public abstract class com/facebook/react/devsupport/DevSupportManagerBase : com/
public fun fetchSplitBundleAndCreateBundleLoader (Ljava/lang/String;Lcom/facebook/react/devsupport/DevSupportManagerBase$CallbackWithBundleLoader;)V
protected fun getApplicationContext ()Landroid/content/Context;
public fun getCurrentActivity ()Landroid/app/Activity;
protected fun getCurrentReactContext ()Lcom/facebook/react/bridge/ReactContext;
public fun getCurrentReactContext ()Lcom/facebook/react/bridge/ReactContext;
public fun getDevLoadingViewManager ()Lcom/facebook/react/devsupport/interfaces/DevLoadingViewManager;
public fun getDevServerHelper ()Lcom/facebook/react/devsupport/DevServerHelper;
public fun getDevSettings ()Lcom/facebook/react/modules/debug/interfaces/DeveloperSettings;
Expand Down Expand Up @@ -2334,6 +2334,7 @@ public class com/facebook/react/devsupport/ReleaseDevSupportManager : com/facebo
public fun destroyRootView (Landroid/view/View;)V
public fun downloadBundleResourceFromUrlSync (Ljava/lang/String;Ljava/io/File;)Ljava/io/File;
public fun getCurrentActivity ()Landroid/app/Activity;
public fun getCurrentReactContext ()Lcom/facebook/react/bridge/ReactContext;
public fun getDevSettings ()Lcom/facebook/react/modules/debug/interfaces/DeveloperSettings;
public fun getDevSupportEnabled ()Z
public fun getDownloadedJSBundleFile ()Ljava/lang/String;
Expand Down Expand Up @@ -2470,6 +2471,7 @@ public abstract interface class com/facebook/react/devsupport/interfaces/DevSupp
public abstract fun destroyRootView (Landroid/view/View;)V
public abstract fun downloadBundleResourceFromUrlSync (Ljava/lang/String;Ljava/io/File;)Ljava/io/File;
public abstract fun getCurrentActivity ()Landroid/app/Activity;
public abstract fun getCurrentReactContext ()Lcom/facebook/react/bridge/ReactContext;
public abstract fun getDevSettings ()Lcom/facebook/react/modules/debug/interfaces/DeveloperSettings;
public abstract fun getDevSupportEnabled ()Z
public abstract fun getDownloadedJSBundleFile ()Ljava/lang/String;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -707,7 +707,7 @@ public void reloadSettings() {
}
}

protected @Nullable ReactContext getCurrentReactContext() {
public @Nullable ReactContext getCurrentReactContext() {
return mCurrentReactContext;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
import androidx.core.view.WindowInsetsCompat;
import com.facebook.common.logging.FLog;
import com.facebook.react.R;
import com.facebook.react.bridge.LifecycleEventListener;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.common.ReactConstants;
import com.facebook.react.common.SurfaceDelegate;
import com.facebook.react.devsupport.interfaces.DevSupportManager;
Expand Down Expand Up @@ -55,7 +57,7 @@ public void createContentView(String appKey) {
FLog.e(
ReactConstants.TAG,
"Unable to launch redbox because react activity "
+ "is not available, here is the error that redbox would've displayed: "
+ "are not available, here is the error that redbox would've displayed: "
+ (message != null ? message : "N/A"));
return;
}
Expand All @@ -82,9 +84,19 @@ public void show() {
@Nullable String message = mDevSupportManager.getLastErrorTitle();
Activity context = mDevSupportManager.getCurrentActivity();
if (context == null || context.isFinishing()) {
final @Nullable ReactContext reactContext = mDevSupportManager.getCurrentReactContext();
if (reactContext != null) {
/**
* If the activity isn't available, try again after the next onHostResume(). onHostResume()
* is when the activity gets attached to the react native.
*/
runAfterHostResume(reactContext, this::show);
return;
}

FLog.e(
ReactConstants.TAG,
"Unable to launch redbox because react activity "
"Unable to launch redbox because react activity and react context "
+ "is not available, here is the error that redbox would've displayed: "
+ (message != null ? message : "N/A"));
return;
Expand Down Expand Up @@ -140,6 +152,23 @@ protected void onCreate(Bundle savedInstanceState) {
mDialog.show();
}

private static void runAfterHostResume(ReactContext reactContext, Runnable runnable) {
reactContext.addLifecycleEventListener(
new LifecycleEventListener() {
@Override
public void onHostResume() {
runnable.run();
reactContext.removeLifecycleEventListener(this);
}

@Override
public void onHostPause() {}

@Override
public void onHostDestroy() {}
});
}

@Override
public void hide() {
// dismiss redbox if exists
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,9 @@ public open class ReleaseDevSupportManager : DevSupportManager {
override public val currentActivity: Activity?
get() = null

override public val currentReactContext: ReactContext?
get() = null

override public fun createSurfaceDelegate(moduleName: String?): SurfaceDelegate? = null

override public fun openDebugger(): Unit = Unit
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public interface DevSupportManager : JSExceptionHandler {
public val lastErrorType: ErrorType?
public val lastErrorCookie: Int
public val currentActivity: Activity?
public val currentReactContext: ReactContext?

public var devSupportEnabled: Boolean

Expand Down

0 comments on commit 0e7ba90

Please sign in to comment.