Merge "Avoid concurrent modification for pending partial layout views"

This commit is contained in:
Alan Viverette
2015-11-30 14:59:23 +00:00
committed by Android (Google) Code Review
2 changed files with 20 additions and 2 deletions

View File

@@ -22369,7 +22369,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* Used to track views that need (at least) a partial relayout at their current size
* during the next traversal.
*/
final List<View> mPartialLayoutViews = new ArrayList<View>();
List<View> mPartialLayoutViews = new ArrayList<>();
/**
* Swapped with mPartialLayoutViews during layout to avoid concurrent
* modification. Lazily assigned during ViewRootImpl layout.
*/
List<View> mEmptyPartialLayoutViews;
/**
* Used to track the identity of the current drag operation.

View File

@@ -1974,6 +1974,15 @@ public final class ViewRootImpl implements ViewParent,
final List<View> partialLayoutViews = mAttachInfo.mPartialLayoutViews;
final boolean didPartialLayout;
if (!partialLayoutViews.isEmpty()) {
// Measurement or layout of views may result in changes to the list
// of partial-layout views. Swap in an "empty" list to prevent
// concurrent modification of the list being traversed.
if (mAttachInfo.mEmptyPartialLayoutViews == null) {
mAttachInfo.mPartialLayoutViews = new ArrayList<>();
} else {
mAttachInfo.mPartialLayoutViews = mAttachInfo.mEmptyPartialLayoutViews;
}
final int count = partialLayoutViews.size();
mInLayout = true;
for (int i = 0; i < count; i++) {
@@ -1992,9 +2001,12 @@ public final class ViewRootImpl implements ViewParent,
}
}
mInLayout = false;
partialLayoutViews.clear();
didPartialLayout = true;
triggerGlobalLayoutListener = true;
// The traversal list becomes the new empty list.
partialLayoutViews.clear();
mAttachInfo.mEmptyPartialLayoutViews = partialLayoutViews;
} else {
didPartialLayout = false;
}