From f602640e5c95a79973ee74bb8a1f60ba91109680 Mon Sep 17 00:00:00 2001 From: Ahmed El-Helw Date: Thu, 23 Jun 2016 12:25:39 -0700 Subject: [PATCH] Allow for customization of the RootViewManager Summary: Groups encountered a pretty major crash where, in many cases, we would find that DrawCommands and Views were out of sync. This turns out to be due to the fact that when we drop views from the root view, we remove each child using removeChildAt (which ultimately causes an invalidate and redraw). If this happens for a FlatViewGroup, this causes issues where the Views are all removed, but there are some DrawCommands (potentially DrawViews) that aren't removed, hence them going out of sync. Reviewed By: astreet Differential Revision: D3473916 --- .../flat/FlatNativeViewHierarchyManager.java | 2 +- .../react/flat/FlatRootViewManager.java | 22 +++++++++++++++++++ .../facebook/react/flat/FlatViewGroup.java | 10 +++++++++ .../facebook/react/flat/FlatViewManager.java | 5 +++++ 4 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 ReactAndroid/src/main/java/com/facebook/react/flat/FlatRootViewManager.java diff --git a/ReactAndroid/src/main/java/com/facebook/react/flat/FlatNativeViewHierarchyManager.java b/ReactAndroid/src/main/java/com/facebook/react/flat/FlatNativeViewHierarchyManager.java index ed8127793..cbdabed8b 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/flat/FlatNativeViewHierarchyManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/flat/FlatNativeViewHierarchyManager.java @@ -32,7 +32,7 @@ import com.facebook.react.uimanager.ViewManagerRegistry; implements ViewResolver { /* package */ FlatNativeViewHierarchyManager(ViewManagerRegistry viewManagers) { - super(viewManagers); + super(viewManagers, new FlatRootViewManager()); } @Override diff --git a/ReactAndroid/src/main/java/com/facebook/react/flat/FlatRootViewManager.java b/ReactAndroid/src/main/java/com/facebook/react/flat/FlatRootViewManager.java new file mode 100644 index 000000000..6451d62d2 --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/flat/FlatRootViewManager.java @@ -0,0 +1,22 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +package com.facebook.react.flat; + +import android.view.ViewGroup; + +import com.facebook.react.uimanager.RootViewManager; + +/* package */ class FlatRootViewManager extends RootViewManager { + + @Override + public void removeAllViews(ViewGroup parent) { + parent.removeAllViewsInLayout(); + } +} diff --git a/ReactAndroid/src/main/java/com/facebook/react/flat/FlatViewGroup.java b/ReactAndroid/src/main/java/com/facebook/react/flat/FlatViewGroup.java index 60780d3f8..0d64f58d6 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/flat/FlatViewGroup.java +++ b/ReactAndroid/src/main/java/com/facebook/react/flat/FlatViewGroup.java @@ -451,6 +451,16 @@ import com.facebook.react.views.view.ReactClippingViewGroupHelper; removeDetachedView(view, false); } + @Override + public void removeAllViewsInLayout() { + // whenever we want to remove all views in a layout, we also want to remove all the + // DrawCommands, otherwise, we can have a mismatch between the DrawView DrawCommands + // and the Views to draw (note that because removeAllViewsInLayout doesn't call invalidate, + // we don't actually need to modify mDrawCommands, but we do it just in case). + mDrawCommands = DrawCommand.EMPTY_ARRAY; + super.removeAllViewsInLayout(); + } + /* package */ void mountAttachDetachListeners(AttachDetachListener[] listeners) { if (mIsAttached) { // Ordering of the following 2 statements is very important. While logically it makes sense to diff --git a/ReactAndroid/src/main/java/com/facebook/react/flat/FlatViewManager.java b/ReactAndroid/src/main/java/com/facebook/react/flat/FlatViewManager.java index dd807c80a..5bfe0aee6 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/flat/FlatViewManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/flat/FlatViewManager.java @@ -23,4 +23,9 @@ abstract class FlatViewManager extends ViewGroupManager { public void setBackgroundColor(FlatViewGroup view, int backgroundColor) { // suppress } + + @Override + public void removeAllViews(FlatViewGroup parent) { + parent.removeAllViewsInLayout(); + } }