Add log to view that is being dropped

Summary:
We are getting errors where views are being dropped twice.
This is following from logic that viewManagers are only removed from `mTagsToViewManagers` from `dropView`.

This log will hopefully identify if we are getting improper operations because we shouldn't be re-using tags

Reviewed By: mdvacca

Differential Revision: D15152869

fbshipit-source-id: 914ee9c1772fa066adefde0753075ecba6377a0c
This commit is contained in:
Luna Wei 2019-05-13 10:57:33 -07:00 коммит произвёл Facebook Github Bot
Родитель 2cd6c0c82e
Коммит 0d7a0dc997
2 изменённых файлов: 23 добавлений и 1 удалений

Просмотреть файл

@ -37,4 +37,10 @@ public class ReactFeatureFlags {
* C++ CatalystInstanceImpl
*/
public static boolean useTurboModules = false;
/**
* Log tags of when a view deleted on the native side
* {@link com.facebook.react.uimanager.NativeViewHierarchyManager dropView}
*/
public static boolean logDroppedViews = false;
}

Просмотреть файл

@ -28,11 +28,13 @@ import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.SoftAssertions;
import com.facebook.react.bridge.UiThreadUtil;
import com.facebook.react.config.ReactFeatureFlags;
import com.facebook.react.touch.JSResponderHandler;
import com.facebook.react.uimanager.layoutanimation.LayoutAnimationController;
import com.facebook.react.uimanager.layoutanimation.LayoutAnimationListener;
import com.facebook.systrace.Systrace;
import com.facebook.systrace.SystraceMessage;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.Nullable;
@ -73,9 +75,11 @@ public class NativeViewHierarchyManager {
private final RootViewManager mRootViewManager;
private final LayoutAnimationController mLayoutAnimator = new LayoutAnimationController();
private final Map<Integer, SparseIntArray> mTagsToPendingIndicesToDelete = new HashMap<>();
private final int[] mDroppedViewArray = new int[100];
private boolean mLayoutAnimationEnabled;
private PopupMenu mPopupMenu;
private int mDroppedViewIndex = 0;
public NativeViewHierarchyManager(ViewManagerRegistry viewManagers) {
this(viewManagers, new RootViewManager());
@ -101,7 +105,11 @@ public class NativeViewHierarchyManager {
public synchronized final ViewManager resolveViewManager(int tag) {
ViewManager viewManager = mTagsToViewManagers.get(tag);
if (viewManager == null) {
throw new IllegalViewOperationException("ViewManager for tag " + tag + " could not be found");
boolean alreadyDropped = Arrays.asList(mDroppedViewArray).contains(tag);
throw new IllegalViewOperationException("ViewManager for tag "
+ tag + " could not be found.\n View already dropped? "
+ alreadyDropped + ".\nLast index "+ mDroppedViewIndex + " in last 100 views"
+ mDroppedViewArray.toString());
}
return viewManager;
}
@ -587,6 +595,11 @@ public class NativeViewHierarchyManager {
view.setId(tag);
}
private void cacheDroppedTag(int tag) {
mDroppedViewArray[mDroppedViewIndex] = tag;
mDroppedViewIndex = (mDroppedViewIndex + 1) % 100;
}
/**
* Releases all references to given native View.
*/
@ -596,6 +609,9 @@ public class NativeViewHierarchyManager {
// Ignore this drop operation when view is null.
return;
}
if (ReactFeatureFlags.logDroppedViews) {
cacheDroppedTag(view.getId());
}
if (mTagsToViewManagers.get(view.getId()) == null) {
// This view has already been dropped (likely due to a threading issue caused by async js
// execution). Ignore this drop operation.