mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Implement getReactApplicationContextIfActiveOrWarn in ReactContextBaseJavaModule to generalize checking hasActiveCatalystInstance and warning when it's dead
Summary: In three previous diffs (D18020359 D17998627 D17969056), I implemented this logic in three different modules. There are potentially hundreds of modules where we should be implementing this check, so I'm moving the important logic into ReactContextBaseJavaModule. Additionally, `WebSocketModule` was retaining its own copy of ReactApplicationContext instead of using the built-in `getReactApplicationContext`, so I removed that ivar from `WebSocketModule`. Changelog: [Internal] Reviewed By: mdvacca Differential Revision: D18032458 fbshipit-source-id: 9114120d3b80334df8d2e0813e36d21c667fc1bd
This commit is contained in:
committed by
Facebook Github Bot
parent
e21ed675ec
commit
b12a29cfcb
+36
-1
@@ -7,9 +7,14 @@
|
||||
|
||||
package com.facebook.react.bridge;
|
||||
|
||||
import static com.facebook.infer.annotation.ThreadConfined.ANY;
|
||||
|
||||
import android.app.Activity;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.facebook.common.logging.FLog;
|
||||
import com.facebook.infer.annotation.ThreadConfined;
|
||||
import com.facebook.react.common.build.ReactBuildConfig;
|
||||
|
||||
/**
|
||||
* Base class for Catalyst native modules that require access to the {@link ReactContext} instance.
|
||||
@@ -22,11 +27,41 @@ public abstract class ReactContextBaseJavaModule extends BaseJavaModule {
|
||||
mReactApplicationContext = reactContext;
|
||||
}
|
||||
|
||||
/** Subclasses can use this method to access catalyst context passed as a constructor */
|
||||
/** Subclasses can use this method to access catalyst context passed as a constructor. */
|
||||
protected final ReactApplicationContext getReactApplicationContext() {
|
||||
return mReactApplicationContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses can use this method to access catalyst context passed as a constructor. Use this
|
||||
* version to check that the underlying CatalystInstance is active before returning, and
|
||||
* automatically have SoftExceptions or debug information logged for you. Consider using this
|
||||
* whenever calling ReactApplicationContext methods that require the Catalyst instance be alive.
|
||||
*
|
||||
* <p>This can return null at any time, but especially during teardown methods it's
|
||||
* possible/likely.
|
||||
*
|
||||
* <p>Threading implications have not been analyzed fully yet, so assume this method is not
|
||||
* thread-safe.
|
||||
*/
|
||||
@ThreadConfined(ANY)
|
||||
protected @Nullable final ReactApplicationContext getReactApplicationContextIfActiveOrWarn(
|
||||
String tag, String reason) {
|
||||
if (mReactApplicationContext.hasActiveCatalystInstance()) {
|
||||
return mReactApplicationContext;
|
||||
}
|
||||
|
||||
// We want to collect data about how often this happens, but SoftExceptions will cause a crash
|
||||
// in debug mode, which isn't usually desirable.
|
||||
String msg = "Catalyst Instance has already disappeared: " + reason;
|
||||
if (ReactBuildConfig.DEBUG) {
|
||||
FLog.w(tag, msg);
|
||||
} else {
|
||||
ReactSoftException.logSoftException(tag, new RuntimeException(msg));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the activity to which this context is currently attached, or {@code null} if not attached.
|
||||
*
|
||||
|
||||
@@ -7,18 +7,15 @@
|
||||
|
||||
package com.facebook.react.modules.appstate;
|
||||
|
||||
import android.util.Log;
|
||||
import com.facebook.react.bridge.Arguments;
|
||||
import com.facebook.react.bridge.Callback;
|
||||
import com.facebook.react.bridge.LifecycleEventListener;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||
import com.facebook.react.bridge.ReactMethod;
|
||||
import com.facebook.react.bridge.ReactSoftException;
|
||||
import com.facebook.react.bridge.WindowFocusChangeListener;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.facebook.react.common.LifecycleState;
|
||||
import com.facebook.react.common.build.ReactBuildConfig;
|
||||
import com.facebook.react.module.annotations.ReactModule;
|
||||
import com.facebook.react.modules.core.DeviceEventManagerModule.RCTDeviceEventEmitter;
|
||||
import java.util.HashMap;
|
||||
@@ -96,21 +93,12 @@ public class AppStateModule extends ReactContextBaseJavaModule
|
||||
}
|
||||
|
||||
private void sendEvent(String eventName, @Nullable Object data) {
|
||||
ReactApplicationContext reactApplicationContext = getReactApplicationContext();
|
||||
ReactApplicationContext reactApplicationContext =
|
||||
getReactApplicationContextIfActiveOrWarn(
|
||||
TAG, "sendAppStateChangeEvent: trying to update app state");
|
||||
|
||||
if (reactApplicationContext.hasActiveCatalystInstance()) {
|
||||
if (reactApplicationContext != null) {
|
||||
reactApplicationContext.getJSModule(RCTDeviceEventEmitter.class).emit(eventName, data);
|
||||
} else {
|
||||
// We want to collect data about how often this happens, but this will cause a crash
|
||||
// in debug, which isn't desirable.
|
||||
String msg =
|
||||
"sendAppStateChangeEvent: trying to update app state when Catalyst Instance has already disappeared: "
|
||||
+ eventName;
|
||||
if (ReactBuildConfig.DEBUG) {
|
||||
Log.e(AppStateModule.TAG, msg);
|
||||
} else {
|
||||
ReactSoftException.logSoftException(AppStateModule.TAG, new RuntimeException(msg));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+8
-18
@@ -7,22 +7,18 @@
|
||||
|
||||
package com.facebook.react.modules.websocket;
|
||||
|
||||
import android.util.Log;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.facebook.common.logging.FLog;
|
||||
import com.facebook.react.bridge.Arguments;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.ReactContext;
|
||||
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||
import com.facebook.react.bridge.ReactMethod;
|
||||
import com.facebook.react.bridge.ReactSoftException;
|
||||
import com.facebook.react.bridge.ReadableArray;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.bridge.ReadableMapKeySetIterator;
|
||||
import com.facebook.react.bridge.ReadableType;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.facebook.react.common.ReactConstants;
|
||||
import com.facebook.react.common.build.ReactBuildConfig;
|
||||
import com.facebook.react.module.annotations.ReactModule;
|
||||
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
||||
import com.facebook.react.modules.network.ForwardingCookieHandler;
|
||||
@@ -43,6 +39,8 @@ import okio.ByteString;
|
||||
|
||||
@ReactModule(name = WebSocketModule.NAME, hasConstants = false)
|
||||
public final class WebSocketModule extends ReactContextBaseJavaModule {
|
||||
public static final String TAG = WebSocketModule.class.getSimpleName();
|
||||
|
||||
public static final String NAME = "WebSocketModule";
|
||||
|
||||
public interface ContentHandler {
|
||||
@@ -54,30 +52,22 @@ public final class WebSocketModule extends ReactContextBaseJavaModule {
|
||||
private final Map<Integer, WebSocket> mWebSocketConnections = new ConcurrentHashMap<>();
|
||||
private final Map<Integer, ContentHandler> mContentHandlers = new ConcurrentHashMap<>();
|
||||
|
||||
private ReactContext mReactContext;
|
||||
private ForwardingCookieHandler mCookieHandler;
|
||||
|
||||
public WebSocketModule(ReactApplicationContext context) {
|
||||
super(context);
|
||||
mReactContext = context;
|
||||
mCookieHandler = new ForwardingCookieHandler(context);
|
||||
}
|
||||
|
||||
private void sendEvent(String eventName, WritableMap params) {
|
||||
if (mReactContext.hasActiveCatalystInstance()) {
|
||||
mReactContext
|
||||
ReactApplicationContext reactApplicationContext =
|
||||
getReactApplicationContextIfActiveOrWarn(
|
||||
TAG, "sendAppStateChangeEvent: trying to update app state");
|
||||
|
||||
if (reactApplicationContext != null) {
|
||||
reactApplicationContext
|
||||
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
|
||||
.emit(eventName, params);
|
||||
} else {
|
||||
// We want to collect data about how often this happens, but raising a SoftException in Debug
|
||||
// will cause a crash, which isn't desirable.
|
||||
String msg =
|
||||
"sendEvent: trying to update app state when Catalyst Instance has already disappeared";
|
||||
if (ReactBuildConfig.DEBUG) {
|
||||
Log.e(NAME, msg);
|
||||
} else {
|
||||
ReactSoftException.logSoftException(NAME, new IllegalStateException(msg));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user