android: don't process touch events too early

Summary: There can be a race when loading JS from rootview for the first time vs touching rootview before JS is ready. This may cause redbox on the JS side.

Reviewed By: mdvacca

Differential Revision: D7531334

fbshipit-source-id: 36ffa1e5ff205f60b95e0a1d1016301ea76936aa
This commit is contained in:
Kevin Gozali 2018-04-06 17:16:55 -07:00 committed by Facebook Github Bot
parent b0fa3228a7
commit 667ca15893
1 changed files with 19 additions and 2 deletions

View File

@ -84,7 +84,7 @@ public class ReactRootView extends SizeMonitoringFrameLayout
private int mRootViewTag;
private boolean mIsAttachedToInstance;
private boolean mShouldLogContentAppeared;
private final JSTouchDispatcher mJSTouchDispatcher = new JSTouchDispatcher(this);
private @Nullable JSTouchDispatcher mJSTouchDispatcher;
private final ReactAndroidHWInputDeviceHelper mAndroidHWInputDeviceHelper = new ReactAndroidHWInputDeviceHelper(this);
private boolean mWasMeasured = false;
private int mWidthMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
@ -183,6 +183,12 @@ public class ReactRootView extends SizeMonitoringFrameLayout
"Unable to dispatch touch to JS as the catalyst instance has not been attached");
return;
}
if (mJSTouchDispatcher == null) {
FLog.w(
ReactConstants.TAG,
"Unable to dispatch touch to JS before the dispatcher is available");
return;
}
ReactContext reactContext = mReactInstanceManager.getCurrentReactContext();
EventDispatcher eventDispatcher = reactContext.getNativeModule(UIManagerModule.class)
.getEventDispatcher();
@ -264,6 +270,12 @@ public class ReactRootView extends SizeMonitoringFrameLayout
"Unable to dispatch touch to JS as the catalyst instance has not been attached");
return;
}
if (mJSTouchDispatcher == null) {
FLog.w(
ReactConstants.TAG,
"Unable to dispatch touch to JS before the dispatcher is available");
return;
}
ReactContext reactContext = mReactInstanceManager.getCurrentReactContext();
EventDispatcher eventDispatcher = reactContext.getNativeModule(UIManagerModule.class)
.getEventDispatcher();
@ -414,6 +426,11 @@ public class ReactRootView extends SizeMonitoringFrameLayout
}
public void onAttachedToReactInstance() {
// Create the touch dispatcher here instead of having it always available, to make sure
// that all touch events are only passed to JS after React/JS side is ready to consume
// them. Otherwise, these events might break the states expected by JS.
// Note that this callback was invoked from within the UI thread.
mJSTouchDispatcher = new JSTouchDispatcher(this);
if (mRootViewEventListener != null) {
mRootViewEventListener.onAttachedToReactInstance(this);
}
@ -582,7 +599,7 @@ public class ReactRootView extends SizeMonitoringFrameLayout
public ReactInstanceManager getReactInstanceManager() {
return mReactInstanceManager;
}
/* package */ void sendEvent(String eventName, @Nullable WritableMap params) {
if (mReactInstanceManager != null) {
mReactInstanceManager.getCurrentReactContext()