From f6b4dc68deee7f8df4e19d9293131027ff35b3c5 Mon Sep 17 00:00:00 2001 From: Denis Koroskin Date: Tue, 22 Dec 2015 11:41:07 -0800 Subject: [PATCH] Make sure shadow node that we set JSResponder to mounts to a View Summary: When setJSResponder() is called on a shadow node that doesn't mount to a View, React runtime will crash in NativeViewHierarchyManager because it will fail to find a corresponding View. To fix the issue, make sure we forceMountToView() before we call enqueueSetJSResponder(). Reviewed By: ahmedre Differential Revision: D2779523 --- .../react/flat/FlatUIImplementation.java | 19 +++++++++++++++++++ .../com/facebook/react/flat/StateBuilder.java | 4 ++++ 2 files changed, 23 insertions(+) diff --git a/ReactAndroid/src/main/java/com/facebook/react/flat/FlatUIImplementation.java b/ReactAndroid/src/main/java/com/facebook/react/flat/FlatUIImplementation.java index a54e05d77..0cea29964 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/flat/FlatUIImplementation.java +++ b/ReactAndroid/src/main/java/com/facebook/react/flat/FlatUIImplementation.java @@ -355,6 +355,25 @@ public class FlatUIImplementation extends UIImplementation { mStateBuilder.applyUpdates(eventDispatcher, rootNode); } + @Override + public void setJSResponder(int possiblyVirtualReactTag, boolean blockNativeResponder) { + ReactShadowNode node = resolveShadowNode(possiblyVirtualReactTag); + while (node.isVirtual()) { + node = node.getParent(); + } + + FlatShadowNode nonVirtualNode = (FlatShadowNode) node; + int nonVirtualTag = nonVirtualNode.getReactTag(); + nonVirtualNode.forceMountToView(); + mStateBuilder.ensureBackingViewIsCreated(nonVirtualNode, nonVirtualTag, null); + + FlatUIViewOperationQueue operationsQueue = mStateBuilder.getOperationsQueue(); + operationsQueue.enqueueSetJSResponder( + nonVirtualTag, + possiblyVirtualReactTag, + blockNativeResponder); + } + private static @Nullable ReactImageManager findReactImageManager(List viewManagers) { for (int i = 0, size = viewManagers.size(); i != size; ++i) { if (viewManagers.get(i) instanceof ReactImageManager) { diff --git a/ReactAndroid/src/main/java/com/facebook/react/flat/StateBuilder.java b/ReactAndroid/src/main/java/com/facebook/react/flat/StateBuilder.java index 31e0243f7..989a27618 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/flat/StateBuilder.java +++ b/ReactAndroid/src/main/java/com/facebook/react/flat/StateBuilder.java @@ -52,6 +52,10 @@ import com.facebook.react.uimanager.events.EventDispatcher; mOperationsQueue = operationsQueue; } + /* package */ FlatUIViewOperationQueue getOperationsQueue() { + return mOperationsQueue; + } + /** * Given a root of the laid-out shadow node hierarchy, walks the tree and generates an array of * DrawCommands that will then mount in UI thread to a root FlatViewGroup so that it can draw.