Skip to content

Commit be282b5

Browse files
ayc1facebook-github-bot
authored andcommittedNov 10, 2018
Fix ReactRootView attachRootView race condition
Summary: Yet another issue with mAttachedRootViews. Every time attachRootView is called, the root view's id is reset to NO_ID. However, there can be a case where the react context has not initialized yet, so we delay attaching the root view to the instance manager until setupReactContext. If attachRootView was called a second time before the react context has finished initializing, we end up in a situation where we try to attach the same root view twice I'm planning to remove mAttachedRootViews all together in a future diff, but for now let's avoid these crashes. Reviewed By: mmmulani Differential Revision: D12835167 fbshipit-source-id: ebef3fadc5f9f467eebb3b5644c685acc5ea10bf
1 parent d4aef08 commit be282b5

File tree

2 files changed

+27
-6
lines changed

2 files changed

+27
-6
lines changed
 

‎ReactAndroid/src/androidTest/java/com/facebook/react/tests/core/ReactInstanceManagerTest.java

+23-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package com.facebook.react.tests.core;
77

88
import android.app.Activity;
9+
import android.support.test.InstrumentationRegistry;
910
import android.support.test.annotation.UiThreadTest;
1011
import android.support.test.rule.ActivityTestRule;
1112
import android.support.test.runner.AndroidJUnit4;
@@ -14,6 +15,7 @@
1415
import com.facebook.react.common.LifecycleState;
1516
import com.facebook.react.shell.MainReactPackage;
1617
import com.facebook.react.testing.ReactTestHelper;
18+
import org.junit.After;
1719
import org.junit.Before;
1820
import org.junit.Rule;
1921
import org.junit.Test;
@@ -43,6 +45,19 @@ public void setup() {
4345
.build();
4446
}
4547

48+
@After
49+
public void tearDown() {
50+
final ReactRootView reactRootView = mReactRootView;
51+
final ReactInstanceManager reactInstanceManager = mReactInstanceManager;
52+
InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
53+
@Override
54+
public void run() {
55+
reactRootView.unmountReactApplication();
56+
reactInstanceManager.destroy();
57+
}
58+
});
59+
}
60+
4661
@Test
4762
@UiThreadTest
4863
public void testMountUnmount() {
@@ -56,7 +71,6 @@ public void testMountUnmount() {
5671
public void testResume() throws InterruptedException {
5772
mReactInstanceManager.onHostResume(mActivityRule.getActivity());
5873
mReactRootView.startReactApplication(mReactInstanceManager, TEST_MODULE);
59-
Thread.sleep(1000);
6074
mReactInstanceManager.onHostResume(mActivityRule.getActivity());
6175
}
6276

@@ -65,7 +79,14 @@ public void testResume() throws InterruptedException {
6579
public void testRecreateContext() throws InterruptedException {
6680
mReactInstanceManager.onHostResume(mActivityRule.getActivity());
6781
mReactInstanceManager.createReactContextInBackground();
68-
Thread.sleep(1000);
6982
mReactRootView.startReactApplication(mReactInstanceManager, TEST_MODULE);
7083
}
84+
85+
@Test
86+
@UiThreadTest
87+
public void testMountTwice() {
88+
mReactInstanceManager.onHostResume(mActivityRule.getActivity());
89+
mReactRootView.startReactApplication(mReactInstanceManager, TEST_MODULE);
90+
mReactInstanceManager.attachRootView(mReactRootView);
91+
}
7192
}

‎ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@
9999
import java.util.List;
100100
import java.util.Map;
101101
import java.util.Set;
102+
import java.util.concurrent.ConcurrentHashMap;
102103
import javax.annotation.Nullable;
103104

104105
/**
@@ -134,8 +135,8 @@ public interface ReactInstanceEventListener {
134135
void onReactContextInitialized(ReactContext context);
135136
}
136137

137-
private final List<ReactRootView> mAttachedRootViews = Collections.synchronizedList(
138-
new ArrayList<ReactRootView>());
138+
private final Set<ReactRootView> mAttachedRootViews = Collections.synchronizedSet(
139+
new HashSet<ReactRootView>());
139140

140141
private volatile LifecycleState mLifecycleState;
141142

@@ -1037,8 +1038,7 @@ public void run() {
10371038
});
10381039
}
10391040

1040-
private void attachRootViewToInstance(
1041-
final ReactRootView rootView) {
1041+
private void attachRootViewToInstance(final ReactRootView rootView) {
10421042
Log.d(ReactConstants.TAG, "ReactInstanceManager.attachRootViewToInstance()");
10431043
Systrace.beginSection(TRACE_TAG_REACT_JAVA_BRIDGE, "attachRootViewToInstance");
10441044
UIManager uiManagerModule = UIManagerHelper.getUIManager(mCurrentReactContext, rootView.getUIManagerType());

0 commit comments

Comments
 (0)
Please sign in to comment.