From a9c88bce14d98096ccea15b90be7e92413343a41 Mon Sep 17 00:00:00 2001 From: Denis Koroskin Date: Wed, 24 Feb 2016 20:16:40 -0800 Subject: [PATCH] Fix 2 bugs in FlatUIImplementation.removeChild() Summary: There are 2 issues in removeChild() implementation. a) There is a chance that a node that we are removing will be mounting to a View, but the create view request has not be created so there is no backing View for it yet. In that case, FlatNativeViewHierarchyManager.dropView() will throw an Exception failing to find the View. The fix is to only dropView() if one was (requested to be) created. b) If the shadow node that we are removing doesn't mount to a View, but one or more of its children do, those Views will leak because noone is removing them. The fix is to recursively call removeChild() until we find a node that mounts to a View. Reviewed By: ahmedre Differential Revision: D2974938 --- .../java/com/facebook/react/flat/FlatUIImplementation.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) 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 360e36e5707..dccc59d6cad 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/flat/FlatUIImplementation.java +++ b/ReactAndroid/src/main/java/com/facebook/react/flat/FlatUIImplementation.java @@ -274,10 +274,15 @@ public class FlatUIImplementation extends UIImplementation { * and drops all Views used by it and its children. */ private void removeChild(FlatShadowNode child) { - if (child.mountsToView()) { + if (child.mountsToView() && child.isBackingViewCreated()) { // this will recursively drop all subviews mStateBuilder.dropView(child); + } else { + for (int i = 0, childCount = child.getChildCount(); i != childCount; ++i) { + removeChild((FlatShadowNode) child.getChildAt(i)); + } } + removeShadowNode(child); }