From c4ae445edee316b5e22ccc5aa3ccb8b640f73b8b Mon Sep 17 00:00:00 2001 From: Fengjiang Li Date: Fri, 25 Apr 2025 15:41:27 -0700 Subject: [PATCH] [Memory Leak] Avoid adding duplicated OnScrollChangedListener to RecentsView Use ArraySet to replace List to avoid duplication Fix: 413449336 Test: presubmit Flag: NONE - release code Change-Id: I3bc21fe09ae8e6d5de4ad0389fbd1d723a620c2e --- .../com/android/quickstep/views/RecentsView.java | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index 6d1e8efc23..57fd9ee068 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -109,6 +109,7 @@ import android.os.VibrationEffect; import android.text.Layout; import android.text.StaticLayout; import android.text.TextPaint; +import android.util.ArraySet; import android.util.AttributeSet; import android.util.FloatProperty; import android.util.Log; @@ -142,6 +143,7 @@ import androidx.dynamicanimation.animation.SpringAnimation; import com.android.internal.jank.Cuj; import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.BaseActivity.MultiWindowModeChangedListener; +import com.android.launcher3.BuildConfig; import com.android.launcher3.DeviceProfile; import com.android.launcher3.Insettable; import com.android.launcher3.PagedView; @@ -546,7 +548,7 @@ public abstract class RecentsView< private final PointF mTempPointF = new PointF(); private final Matrix mTempMatrix = new Matrix(); private final float[] mTempFloat = new float[1]; - private final List mScrollListeners = new ArrayList<>(); + private final ArraySet mScrollListeners = new ArraySet<>(); // The threshold at which we update the SystemUI flags when animating from the task into the app public static final float UPDATE_SYSUI_FLAGS_THRESHOLD = 0.85f; @@ -6733,6 +6735,14 @@ public abstract class RecentsView< * Adds a listener for scroll changes */ public void addOnScrollChangedListener(OnScrollChangedListener listener) { + if (mScrollListeners.contains(listener)) { + if (BuildConfig.IS_STUDIO_BUILD) { + throw new IllegalStateException( + "Should not add duplicated OnScrollChangedListener"); + } else { + mScrollListeners.remove(listener); + } + } mScrollListeners.add(listener); } @@ -6867,7 +6877,7 @@ public abstract class RecentsView< runActionOnRemoteHandles(remoteTargetHandle -> remoteTargetHandle.getTaskViewSimulator().setScroll(getScrollOffset())); for (int i = mScrollListeners.size() - 1; i >= 0; i--) { - mScrollListeners.get(i).onScrollChanged(); + mScrollListeners.valueAt(i).onScrollChanged(); } }