don't block attaching ReactRootView on measuring

Reviewed By: achen1

Differential Revision: D5117394

fbshipit-source-id: 00f65a59247a75d4b42240fe25935aa9bd8948b1
This commit is contained in:
Aaron Chiu
2017-05-31 02:16:43 -07:00
committed by Facebook Github Bot
parent 23a34d4c65
commit 8125ce520d
12 changed files with 31 additions and 42 deletions

View File

@@ -613,7 +613,7 @@ public class ReactInstanceManager {
* be re-attached.
*/
@ThreadConfined(UI)
public void attachMeasuredRootView(ReactRootView rootView) {
public void attachRootView(ReactRootView rootView) {
UiThreadUtil.assertOnUiThread();
mAttachedRootViews.add(rootView);
@@ -624,7 +624,7 @@ public class ReactInstanceManager {
// If react context is being created in the background, JS application will be started
// automatically when creation completes, as root view is part of the attached root view list.
if (mCreateReactContextThread == null && mCurrentReactContext != null) {
attachMeasuredRootViewToInstance(rootView, mCurrentReactContext.getCatalystInstance());
attachRootViewToInstance(rootView, mCurrentReactContext.getCatalystInstance());
}
}
@@ -814,7 +814,7 @@ public class ReactInstanceManager {
ReactMarker.logMarker(ATTACH_MEASURED_ROOT_VIEWS_START);
synchronized (mAttachedRootViews) {
for (ReactRootView rootView : mAttachedRootViews) {
attachMeasuredRootViewToInstance(rootView, catalystInstance);
attachRootViewToInstance(rootView, catalystInstance);
}
}
ReactMarker.logMarker(ATTACH_MEASURED_ROOT_VIEWS_END);
@@ -850,16 +850,16 @@ public class ReactInstanceManager {
}
}
private void attachMeasuredRootViewToInstance(
private void attachRootViewToInstance(
final ReactRootView rootView,
CatalystInstance catalystInstance) {
Systrace.beginSection(TRACE_TAG_REACT_JAVA_BRIDGE, "attachMeasuredRootViewToInstance");
Systrace.beginSection(TRACE_TAG_REACT_JAVA_BRIDGE, "attachRootViewToInstance");
if (!mSetupReactContextInBackgroundEnabled) {
UiThreadUtil.assertOnUiThread();
}
UIManagerModule uiManagerModule = catalystInstance.getNativeModule(UIManagerModule.class);
final int rootTag = uiManagerModule.addMeasuredRootView(rootView);
final int rootTag = uiManagerModule.addRootView(rootView);
rootView.setRootViewTag(rootTag);
rootView.runApplication();
Systrace.beginAsyncSection(

View File

@@ -78,8 +78,7 @@ public class ReactRootView extends SizeMonitoringFrameLayout implements RootView
private @Nullable CustomGlobalLayoutListener mCustomGlobalLayoutListener;
private @Nullable ReactRootViewEventListener mRootViewEventListener;
private int mRootViewTag;
private boolean mWasMeasured = false;
private boolean mIsAttachedToInstance = false;
private boolean mIsAttachedToInstance;
private final JSTouchDispatcher mJSTouchDispatcher = new JSTouchDispatcher(this);
public ReactRootView(Context context) {
@@ -102,7 +101,6 @@ public class ReactRootView extends SizeMonitoringFrameLayout implements RootView
MeasureSpec.getSize(widthMeasureSpec),
MeasureSpec.getSize(heightMeasureSpec));
mWasMeasured = true;
// Check if we were waiting for onMeasure to attach the root view.
if (mReactInstanceManager != null && !mIsAttachedToInstance) {
attachToReactInstanceManager();
@@ -222,12 +220,7 @@ public class ReactRootView extends SizeMonitoringFrameLayout implements RootView
mReactInstanceManager.createReactContextInBackground();
}
// We need to wait for the initial onMeasure, if this view has not yet been measured, we set
// which will make this view startReactApplication itself to instance manager once onMeasure
// is called.
if (mWasMeasured) {
attachToReactInstanceManager();
}
attachToReactInstanceManager();
} finally {
Systrace.endSection(TRACE_TAG_REACT_JAVA_BRIDGE);
}
@@ -303,13 +296,12 @@ public class ReactRootView extends SizeMonitoringFrameLayout implements RootView
}
/**
* Is used by unit test to setup mWasMeasured and mIsAttachedToWindow flags, that will let this
* Is used by unit test to setup mIsAttachedToWindow flags, that will let this
* view to be properly attached to catalyst instance by startReactApplication call
*/
@VisibleForTesting
/* package */ void simulateAttachForTesting() {
mIsAttachedToInstance = true;
mWasMeasured = true;
}
private CustomGlobalLayoutListener getCustomGlobalLayoutListener() {
@@ -327,7 +319,7 @@ public class ReactRootView extends SizeMonitoringFrameLayout implements RootView
}
mIsAttachedToInstance = true;
Assertions.assertNotNull(mReactInstanceManager).attachMeasuredRootView(this);
Assertions.assertNotNull(mReactInstanceManager).attachRootView(this);
getViewTreeObserver().addOnGlobalLayoutListener(getCustomGlobalLayoutListener());
} finally {
Systrace.endSection(TRACE_TAG_REACT_JAVA_BRIDGE);
@@ -362,6 +354,7 @@ public class ReactRootView extends SizeMonitoringFrameLayout implements RootView
private int mDeviceRotation = 0;
/* package */ CustomGlobalLayoutListener() {
DisplayMetricsHolder.initDisplayMetricsIfNotInitialized(getContext().getApplicationContext());
mVisibleViewArea = new Rect();
mMinKeyboardHeightDetected = (int) PixelUtil.toPixelFromDIP(60);
}

View File

@@ -487,7 +487,7 @@ public class NativeViewHierarchyManager {
}
/**
* See {@link UIManagerModule#addMeasuredRootView}.
* See {@link UIManagerModule#addRootView}.
*/
public synchronized void addRootView(
int tag,
@@ -504,7 +504,7 @@ public class NativeViewHierarchyManager {
throw new IllegalViewOperationException(
"Trying to add a root view with an explicit id already set. React Native uses " +
"the id field to track react tags and will overwrite this field. If that is fine, " +
"explicitly overwrite the id field to View.NO_ID before calling addMeasuredRootView.");
"explicitly overwrite the id field to View.NO_ID before calling addRootView.");
}
mTagsToViews.put(tag, view);

View File

@@ -52,5 +52,4 @@ public class SizeMonitoringFrameLayout extends FrameLayout {
mOnSizeChangedListener.onSizeChanged(w, h, oldw, oldh);
}
}
}

View File

@@ -14,7 +14,6 @@ import java.util.Arrays;
import java.util.List;
import com.facebook.common.logging.FLog;
import com.facebook.yoga.YogaDirection;
import com.facebook.infer.annotation.Assertions;
import com.facebook.react.animation.Animation;
import com.facebook.react.bridge.Arguments;
@@ -30,6 +29,7 @@ import com.facebook.react.uimanager.debug.NotThreadSafeViewHierarchyUpdateDebugL
import com.facebook.react.uimanager.events.EventDispatcher;
import com.facebook.systrace.Systrace;
import com.facebook.systrace.SystraceMessage;
import com.facebook.yoga.YogaDirection;
/**
* An class that is used to receive React commands from JS and translate them into a

View File

@@ -181,13 +181,13 @@ public class UIManagerModule extends ReactContextBaseJavaModule implements
* Note that this must be called after getWidth()/getHeight() actually return something. See
* CatalystApplicationFragment as an example.
*
* TODO(6242243): Make addMeasuredRootView thread safe
* TODO(6242243): Make addRootView thread safe
* NB: this method is horribly not-thread-safe.
*/
public int addMeasuredRootView(final SizeMonitoringFrameLayout rootView) {
public int addRootView(final SizeMonitoringFrameLayout rootView) {
Systrace.beginSection(
Systrace.TRACE_TAG_REACT_JAVA_BRIDGE,
"UIManagerModule.addMeasuredRootView");
"UIManagerModule.addRootView");
final int tag = mNextRootViewTag;
mNextRootViewTag += ROOT_VIEW_TAG_INCREMENT;
@@ -195,8 +195,8 @@ public class UIManagerModule extends ReactContextBaseJavaModule implements
final int height;
// If LayoutParams sets size explicitly, we can use that. Otherwise get the size from the view.
if (rootView.getLayoutParams() != null &&
rootView.getLayoutParams().width > 0 &&
rootView.getLayoutParams().height > 0) {
rootView.getLayoutParams().width > 0 &&
rootView.getLayoutParams().height > 0) {
width = rootView.getLayoutParams().width;
height = rootView.getLayoutParams().height;
} else {
@@ -206,7 +206,7 @@ public class UIManagerModule extends ReactContextBaseJavaModule implements
final ReactApplicationContext reactApplicationContext = getReactApplicationContext();
final ThemedReactContext themedRootContext =
new ThemedReactContext(reactApplicationContext, rootView.getContext());
new ThemedReactContext(reactApplicationContext, rootView.getContext());
mUIImplementation.registerRootView(rootView, tag, width, height, themedRootContext);