mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-04-11 11:29:03 +08:00
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
This commit is contained in:
committed by
Facebook Github Bot
parent
d4aef08af9
commit
be282b5287
@@ -6,6 +6,7 @@
|
||||
package com.facebook.react.tests.core;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
import android.support.test.annotation.UiThreadTest;
|
||||
import android.support.test.rule.ActivityTestRule;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
@@ -14,6 +15,7 @@ import com.facebook.react.ReactRootView;
|
||||
import com.facebook.react.common.LifecycleState;
|
||||
import com.facebook.react.shell.MainReactPackage;
|
||||
import com.facebook.react.testing.ReactTestHelper;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
@@ -43,6 +45,19 @@ public class ReactInstanceManagerTest {
|
||||
.build();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
final ReactRootView reactRootView = mReactRootView;
|
||||
final ReactInstanceManager reactInstanceManager = mReactInstanceManager;
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
reactRootView.unmountReactApplication();
|
||||
reactInstanceManager.destroy();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void testMountUnmount() {
|
||||
@@ -56,7 +71,6 @@ public class ReactInstanceManagerTest {
|
||||
public void testResume() throws InterruptedException {
|
||||
mReactInstanceManager.onHostResume(mActivityRule.getActivity());
|
||||
mReactRootView.startReactApplication(mReactInstanceManager, TEST_MODULE);
|
||||
Thread.sleep(1000);
|
||||
mReactInstanceManager.onHostResume(mActivityRule.getActivity());
|
||||
}
|
||||
|
||||
@@ -65,7 +79,14 @@ public class ReactInstanceManagerTest {
|
||||
public void testRecreateContext() throws InterruptedException {
|
||||
mReactInstanceManager.onHostResume(mActivityRule.getActivity());
|
||||
mReactInstanceManager.createReactContextInBackground();
|
||||
Thread.sleep(1000);
|
||||
mReactRootView.startReactApplication(mReactInstanceManager, TEST_MODULE);
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void testMountTwice() {
|
||||
mReactInstanceManager.onHostResume(mActivityRule.getActivity());
|
||||
mReactRootView.startReactApplication(mReactInstanceManager, TEST_MODULE);
|
||||
mReactInstanceManager.attachRootView(mReactRootView);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,6 +99,7 @@ import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
@@ -134,8 +135,8 @@ public class ReactInstanceManager {
|
||||
void onReactContextInitialized(ReactContext context);
|
||||
}
|
||||
|
||||
private final List<ReactRootView> mAttachedRootViews = Collections.synchronizedList(
|
||||
new ArrayList<ReactRootView>());
|
||||
private final Set<ReactRootView> mAttachedRootViews = Collections.synchronizedSet(
|
||||
new HashSet<ReactRootView>());
|
||||
|
||||
private volatile LifecycleState mLifecycleState;
|
||||
|
||||
@@ -1037,8 +1038,7 @@ public class ReactInstanceManager {
|
||||
});
|
||||
}
|
||||
|
||||
private void attachRootViewToInstance(
|
||||
final ReactRootView rootView) {
|
||||
private void attachRootViewToInstance(final ReactRootView rootView) {
|
||||
Log.d(ReactConstants.TAG, "ReactInstanceManager.attachRootViewToInstance()");
|
||||
Systrace.beginSection(TRACE_TAG_REACT_JAVA_BRIDGE, "attachRootViewToInstance");
|
||||
UIManager uiManagerModule = UIManagerHelper.getUIManager(mCurrentReactContext, rootView.getUIManagerType());
|
||||
|
||||
Reference in New Issue
Block a user