mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-04-06 22:38:37 +08:00
Fix leak in Nodes due to removeClippedSubviews
Summary: The removeClippedSubviews optimization often detaches views while maintaining strong references to them (so they can be attached again later on). However, when removing the parent view, any detached views end up not being cleaned up or removed, thus leaking memory. This fixes this by explicitly dropping detached views when the parent is removed. Reviewed By: astreet Differential Revision: D3337513
This commit is contained in:
@@ -11,6 +11,8 @@ package com.facebook.react.flat;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import android.view.View;
|
||||
import android.view.View.MeasureSpec;
|
||||
import android.view.ViewGroup;
|
||||
@@ -134,6 +136,30 @@ import com.facebook.react.uimanager.ViewManagerRegistry;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dropView(View view) {
|
||||
super.dropView(view);
|
||||
|
||||
// As a result of removeClippedSubviews, some views have strong references but are not attached
|
||||
// to a parent. consequently, when the parent gets removed, these Views don't get cleaned up,
|
||||
// because they aren't children (they also aren't removed from mTagsToViews, thus causing a
|
||||
// leak). To solve this, we ask for said detached views and explicitly drop them.
|
||||
if (view instanceof FlatViewGroup) {
|
||||
FlatViewGroup flatViewGroup = (FlatViewGroup) view;
|
||||
if (flatViewGroup.getRemoveClippedSubviews()) {
|
||||
Collection<FlatViewGroup> detachedViews = flatViewGroup.getDetachedViews();
|
||||
for (FlatViewGroup detachedChild : detachedViews) {
|
||||
// we can do super here because removeClippedSubviews is currently not recursive. if/when
|
||||
// we become recursive one day, this should call vanilla dropView to be recursive as well.
|
||||
super.dropView(detachedChild);
|
||||
// trigger onDetachedFromWindow - this is currently needed due to using attach/detach
|
||||
// instead of add/remove. if we move to add/remove in the future, we can remove this.
|
||||
flatViewGroup.removeDetachedView(detachedChild);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* package */ void detachAllChildrenFromViews(int[] viewsToDetachAllChildrenFrom) {
|
||||
for (int viewTag : viewsToDetachAllChildrenFrom) {
|
||||
View view = resolveView(viewTag);
|
||||
|
||||
Reference in New Issue
Block a user