Do not use InteractionManager to wait for Activity (#35289)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/35289
This was originally added in D15258046 (c802d0b757
) but seems to be the wrong solution to the problem from my perspective. InteractionManager does not provide timing information on the activity being available, but ReactContext's LifecycleEventListener does.
This should also address some of the issues raised in https://github.com/facebook/react-native/issues/25675
Changelog: [Android][Fixed] Linking.getInitialUrl should not wait for InteractionManager
Reviewed By: mdvacca
Differential Revision: D41157646
fbshipit-source-id: 6e23969212570204a7e076b6d4d9db004412da09
This commit is contained in:
Родитель
9125ff065c
Коммит
3921f05f59
|
@ -11,7 +11,6 @@
|
|||
import type {EventSubscription} from '../vendor/emitter/EventEmitter';
|
||||
|
||||
import NativeEventEmitter from '../EventEmitter/NativeEventEmitter';
|
||||
import InteractionManager from '../Interaction/InteractionManager';
|
||||
import Platform from '../Utilities/Platform';
|
||||
import NativeIntentAndroid from './NativeIntentAndroid';
|
||||
import NativeLinkingManager from './NativeLinkingManager';
|
||||
|
@ -96,9 +95,7 @@ class Linking extends NativeEventEmitter<LinkingEventDefinitions> {
|
|||
*/
|
||||
getInitialURL(): Promise<?string> {
|
||||
return Platform.OS === 'android'
|
||||
? InteractionManager.runAfterInteractions().then(() =>
|
||||
nullthrows(NativeIntentAndroid).getInitialURL(),
|
||||
)
|
||||
? nullthrows(NativeIntentAndroid).getInitialURL()
|
||||
: nullthrows(NativeLinkingManager).getInitialURL();
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ import android.provider.Settings;
|
|||
import androidx.annotation.Nullable;
|
||||
import com.facebook.fbreact.specs.NativeIntentAndroidSpec;
|
||||
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
|
||||
import com.facebook.react.bridge.LifecycleEventListener;
|
||||
import com.facebook.react.bridge.Promise;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.ReadableArray;
|
||||
|
@ -30,6 +31,8 @@ public class IntentModule extends NativeIntentAndroidSpec {
|
|||
|
||||
public static final String NAME = "IntentAndroid";
|
||||
|
||||
private @Nullable LifecycleEventListener mInitialURLListener = null;
|
||||
|
||||
private static final String EXTRA_MAP_KEY_FOR_VALUE = "value";
|
||||
|
||||
public IntentModule(ReactApplicationContext reactContext) {
|
||||
|
@ -41,6 +44,15 @@ public class IntentModule extends NativeIntentAndroidSpec {
|
|||
return NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidate() {
|
||||
if (mInitialURLListener != null) {
|
||||
getReactApplicationContext().removeLifecycleEventListener(mInitialURLListener);
|
||||
mInitialURLListener = null;
|
||||
}
|
||||
super.invalidate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the URL the activity was started with
|
||||
*
|
||||
|
@ -50,18 +62,20 @@ public class IntentModule extends NativeIntentAndroidSpec {
|
|||
public void getInitialURL(Promise promise) {
|
||||
try {
|
||||
Activity currentActivity = getCurrentActivity();
|
||||
if (currentActivity == null) {
|
||||
waitForActivityAndGetInitialURL(promise);
|
||||
return;
|
||||
}
|
||||
|
||||
Intent intent = currentActivity.getIntent();
|
||||
String action = intent.getAction();
|
||||
Uri uri = intent.getData();
|
||||
|
||||
String initialURL = null;
|
||||
|
||||
if (currentActivity != null) {
|
||||
Intent intent = currentActivity.getIntent();
|
||||
String action = intent.getAction();
|
||||
Uri uri = intent.getData();
|
||||
|
||||
if (uri != null
|
||||
&& (Intent.ACTION_VIEW.equals(action)
|
||||
|| NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action))) {
|
||||
initialURL = uri.toString();
|
||||
}
|
||||
if (uri != null
|
||||
&& (Intent.ACTION_VIEW.equals(action)
|
||||
|| NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action))) {
|
||||
initialURL = uri.toString();
|
||||
}
|
||||
|
||||
promise.resolve(initialURL);
|
||||
|
@ -72,6 +86,33 @@ public class IntentModule extends NativeIntentAndroidSpec {
|
|||
}
|
||||
}
|
||||
|
||||
private void waitForActivityAndGetInitialURL(final Promise promise) {
|
||||
if (mInitialURLListener != null) {
|
||||
promise.reject(
|
||||
new IllegalStateException(
|
||||
"Cannot await activity from more than one call to getInitialURL"));
|
||||
return;
|
||||
}
|
||||
|
||||
mInitialURLListener =
|
||||
new LifecycleEventListener() {
|
||||
@Override
|
||||
public void onHostResume() {
|
||||
getInitialURL(promise);
|
||||
|
||||
getReactApplicationContext().removeLifecycleEventListener(this);
|
||||
mInitialURLListener = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHostPause() {}
|
||||
|
||||
@Override
|
||||
public void onHostDestroy() {}
|
||||
};
|
||||
getReactApplicationContext().addLifecycleEventListener(mInitialURLListener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a corresponding external activity for the given URL.
|
||||
*
|
||||
|
|
Загрузка…
Ссылка в новой задаче