From b60e36390c6b32c4d54f9ae25c812ef9dee3e30b Mon Sep 17 00:00:00 2001 From: David Vacca Date: Sun, 10 Nov 2024 09:30:58 -0800 Subject: [PATCH] Introduce ReactHost.destroy() method to notifies when the React instance is destroyed (#47534) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47534 This diff is introducing a new method to destroy React instance that allows the caller to be notified when the destroy finishes This is necessary for apps to act upon destroy of the react instance changelog: [internal] internal Reviewed By: shwanton Differential Revision: D65721107 fbshipit-source-id: 2d3d9755db38461ba381b86c72df5869c542379b --- .../ReactAndroid/api/ReactAndroid.api | 3 +++ .../main/java/com/facebook/react/ReactHost.kt | 21 ++++++++++++++++++- .../facebook/react/runtime/ReactHostImpl.java | 20 ++++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 3af665e8bb6..70e3de5e55d 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -205,6 +205,8 @@ public abstract interface class com/facebook/react/ReactHost { public abstract fun addReactInstanceEventListener (Lcom/facebook/react/ReactInstanceEventListener;)V public abstract fun createSurface (Landroid/content/Context;Ljava/lang/String;Landroid/os/Bundle;)Lcom/facebook/react/interfaces/fabric/ReactSurface; public abstract fun destroy (Ljava/lang/String;Ljava/lang/Exception;)Lcom/facebook/react/interfaces/TaskInterface; + public abstract fun destroy (Ljava/lang/String;Ljava/lang/Exception;Lkotlin/jvm/functions/Function1;)Lcom/facebook/react/interfaces/TaskInterface; + public static synthetic fun destroy$default (Lcom/facebook/react/ReactHost;Ljava/lang/String;Ljava/lang/Exception;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lcom/facebook/react/interfaces/TaskInterface; public abstract fun getCurrentReactContext ()Lcom/facebook/react/bridge/ReactContext; public abstract fun getDevSupportManager ()Lcom/facebook/react/devsupport/interfaces/DevSupportManager; public abstract fun getLifecycleState ()Lcom/facebook/react/common/LifecycleState; @@ -3789,6 +3791,7 @@ public class com/facebook/react/runtime/ReactHostImpl : com/facebook/react/React public fun addReactInstanceEventListener (Lcom/facebook/react/ReactInstanceEventListener;)V public fun createSurface (Landroid/content/Context;Ljava/lang/String;Landroid/os/Bundle;)Lcom/facebook/react/interfaces/fabric/ReactSurface; public fun destroy (Ljava/lang/String;Ljava/lang/Exception;)Lcom/facebook/react/interfaces/TaskInterface; + public fun destroy (Ljava/lang/String;Ljava/lang/Exception;Lkotlin/jvm/functions/Function1;)Lcom/facebook/react/interfaces/TaskInterface; public fun getCurrentReactContext ()Lcom/facebook/react/bridge/ReactContext; public fun getDevSupportManager ()Lcom/facebook/react/devsupport/interfaces/DevSupportManager; public fun getLifecycleState ()Lcom/facebook/react/common/LifecycleState; diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactHost.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactHost.kt index b5a88b70574..86409ba182a 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactHost.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactHost.kt @@ -116,7 +116,26 @@ public interface ReactHost { * be used to log properly the cause of destroy operation. * @return A task that completes when React Native gets destroyed. */ - public fun destroy(reason: String, ex: Exception?): TaskInterface + public fun destroy( + reason: String, + ex: Exception?, + ): TaskInterface + + /** + * Entrypoint to destroy the ReactInstance. If the ReactInstance is reloading, will wait until + * reload is finished, before destroying. + * + * @param reason describing why ReactHost is being destroyed (e.g. memmory pressure) + * @param ex exception that caused the trigger to destroy ReactHost (or null) This exception will + * be used to log properly the cause of destroy operation. + * @param onDestroyFinished callback that will be called when React Native gets destroyed. + * @return A task that completes when React Native gets destroyed. + */ + public fun destroy( + reason: String, + ex: Exception?, + onDestroyFinished: (instanceDestroyedSuccessfully: Boolean) -> Unit = {} + ): TaskInterface /** * Permanently destroys the ReactHost, including the ReactInstance (if any). The application MUST diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.java index c0988129387..dd829808466 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactHostImpl.java @@ -86,6 +86,7 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; import kotlin.Unit; import kotlin.jvm.functions.Function0; +import kotlin.jvm.functions.Function1; /** * A ReactHost is an object that manages a single {@link ReactInstance}. A ReactHost can be @@ -542,6 +543,25 @@ public class ReactHostImpl implements ReactHost { InspectorNetworkHelper.loadNetworkResource(url, listener); } + @NonNull + @Override + public TaskInterface destroy( + @NonNull String reason, + @Nullable Exception ex, + @NonNull Function1 onDestroyFinished) { + Task task = (Task) destroy(reason, ex); + return task.continueWith( + new Continuation() { + @Nullable + @Override + public Void then(@NonNull Task task) throws Exception { + boolean instanceDestroyedSuccessfully = task.isCompleted() && !task.isFaulted(); + onDestroyFinished.invoke(instanceDestroyedSuccessfully); + return null; + } + }); + } + /** * Entrypoint to destroy the ReactInstance. If the ReactInstance is reloading, will wait until * reload is finished, before destroying.