Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

This change fixes currently broken ReactContext listeners mechanism. #22318

Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
import com.facebook.react.bridge.queue.ReactQueueConfiguration;
import com.facebook.react.common.LifecycleState;
import java.lang.ref.WeakReference;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.Map;
import java.util.WeakHashMap;
import javax.annotation.Nullable;

/**
Expand All @@ -32,10 +33,10 @@ public class ReactContext extends ContextWrapper {
"ReactContext#getJSModule should only happen once initialize() has been called on your " +
"native module.";

private final CopyOnWriteArraySet<LifecycleEventListener> mLifecycleEventListeners =
new CopyOnWriteArraySet<>();
private final CopyOnWriteArraySet<ActivityEventListener> mActivityEventListeners =
new CopyOnWriteArraySet<>();
private final Map<LifecycleEventListener, Void> mLifecycleEventListeners =
new WeakHashMap<>();
private final Map<ActivityEventListener, Void> mActivityEventListeners =
new WeakHashMap<>();

private LifecycleState mLifecycleState = LifecycleState.BEFORE_CREATE;

Expand Down Expand Up @@ -132,7 +133,11 @@ public LifecycleState getLifecycleState() {
}

public void addLifecycleEventListener(final LifecycleEventListener listener) {
mLifecycleEventListeners.add(listener);

synchronized (mLifecycleEventListeners) {
mLifecycleEventListeners.put(listener, null);
}

if (hasActiveCatalystInstance()) {
switch (mLifecycleState) {
case BEFORE_CREATE:
Expand All @@ -143,8 +148,10 @@ public void addLifecycleEventListener(final LifecycleEventListener listener) {
new Runnable() {
@Override
public void run() {
if (!mLifecycleEventListeners.contains(listener)) {
return;
synchronized (mLifecycleEventListeners) {
if (!mLifecycleEventListeners.containsKey(listener)) {
return;
}
}
try {
listener.onHostResume();
Expand All @@ -161,15 +168,21 @@ public void run() {
}

public void removeLifecycleEventListener(LifecycleEventListener listener) {
mLifecycleEventListeners.remove(listener);
synchronized (mLifecycleEventListeners) {
mLifecycleEventListeners.remove(listener);
}
}

public void addActivityEventListener(ActivityEventListener listener) {
mActivityEventListeners.add(listener);
synchronized (mActivityEventListeners) {
mActivityEventListeners.put(listener, null);
}
}

public void removeActivityEventListener(ActivityEventListener listener) {
mActivityEventListeners.remove(listener);
synchronized (mActivityEventListeners) {
mActivityEventListeners.remove(listener);
}
}

/**
Expand All @@ -179,11 +192,13 @@ public void onHostResume(@Nullable Activity activity) {
mLifecycleState = LifecycleState.RESUMED;
mCurrentActivity = new WeakReference(activity);
ReactMarker.logMarker(ReactMarkerConstants.ON_HOST_RESUME_START);
for (LifecycleEventListener listener : mLifecycleEventListeners) {
try {
listener.onHostResume();
} catch (RuntimeException e) {
handleException(e);
synchronized (mLifecycleEventListeners) {
for (LifecycleEventListener listener : mLifecycleEventListeners.keySet()) {
try {
listener.onHostResume();
} catch (RuntimeException e) {
handleException(e);
}
}
}
ReactMarker.logMarker(ReactMarkerConstants.ON_HOST_RESUME_END);
Expand All @@ -192,11 +207,13 @@ public void onHostResume(@Nullable Activity activity) {
public void onNewIntent(@Nullable Activity activity, Intent intent) {
UiThreadUtil.assertOnUiThread();
mCurrentActivity = new WeakReference(activity);
for (ActivityEventListener listener : mActivityEventListeners) {
try {
listener.onNewIntent(intent);
} catch (RuntimeException e) {
handleException(e);
synchronized (mActivityEventListeners) {
for (ActivityEventListener listener : mActivityEventListeners.keySet()) {
try {
listener.onNewIntent(intent);
} catch (RuntimeException e) {
handleException(e);
}
}
}
}
Expand All @@ -207,11 +224,13 @@ public void onNewIntent(@Nullable Activity activity, Intent intent) {
public void onHostPause() {
mLifecycleState = LifecycleState.BEFORE_RESUME;
ReactMarker.logMarker(ReactMarkerConstants.ON_HOST_PAUSE_START);
for (LifecycleEventListener listener : mLifecycleEventListeners) {
try {
listener.onHostPause();
} catch (RuntimeException e) {
handleException(e);
synchronized (mLifecycleEventListeners) {
for (LifecycleEventListener listener : mLifecycleEventListeners.keySet()) {
try {
listener.onHostPause();
} catch (RuntimeException e) {
handleException(e);
}
}
}
ReactMarker.logMarker(ReactMarkerConstants.ON_HOST_PAUSE_END);
Expand All @@ -223,11 +242,13 @@ public void onHostPause() {
public void onHostDestroy() {
UiThreadUtil.assertOnUiThread();
mLifecycleState = LifecycleState.BEFORE_CREATE;
for (LifecycleEventListener listener : mLifecycleEventListeners) {
try {
listener.onHostDestroy();
} catch (RuntimeException e) {
handleException(e);
synchronized (mLifecycleEventListeners) {
for (LifecycleEventListener listener : mLifecycleEventListeners.keySet()) {
try {
listener.onHostDestroy();
} catch (RuntimeException e) {
handleException(e);
}
}
}
mCurrentActivity = null;
Expand All @@ -248,11 +269,13 @@ public void destroy() {
* Should be called by the hosting Fragment in {@link Fragment#onActivityResult}
*/
public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
for (ActivityEventListener listener : mActivityEventListeners) {
try {
listener.onActivityResult(activity, requestCode, resultCode, data);
} catch (RuntimeException e) {
handleException(e);
synchronized (mActivityEventListeners) {
for (ActivityEventListener listener : mActivityEventListeners.keySet()) {
try {
listener.onActivityResult(activity, requestCode, resultCode, data);
} catch (RuntimeException e) {
handleException(e);
}
}
}
}
Expand Down