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:
Pieter De Baets 2022-11-14 03:38:52 -08:00 коммит произвёл Facebook GitHub Bot
Родитель 9125ff065c
Коммит 3921f05f59
2 изменённых файлов: 53 добавлений и 15 удалений

Просмотреть файл

@ -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.
*