diff --git a/core/java/android/view/accessibility/AccessibilityNodeIdManager.java b/core/java/android/view/accessibility/AccessibilityNodeIdManager.java index 0f5e950582dd7..d78dadd294caf 100644 --- a/core/java/android/view/accessibility/AccessibilityNodeIdManager.java +++ b/core/java/android/view/accessibility/AccessibilityNodeIdManager.java @@ -16,12 +16,11 @@ package android.view.accessibility; -import android.util.SparseArray; import android.view.View; /** @hide */ public final class AccessibilityNodeIdManager { - private SparseArray mIdsToViews = new SparseArray<>(); + private WeakSparseArray mIdsToViews = new WeakSparseArray(); private static AccessibilityNodeIdManager sIdManager; /** diff --git a/core/java/android/view/accessibility/WeakSparseArray.java b/core/java/android/view/accessibility/WeakSparseArray.java new file mode 100644 index 0000000000000..04a4cc7f062b2 --- /dev/null +++ b/core/java/android/view/accessibility/WeakSparseArray.java @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.view.accessibility; + +import android.util.SparseArray; + +import java.lang.ref.Reference; +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; + + +final class WeakSparseArray { + + private final ReferenceQueue mRefQueue = new ReferenceQueue<>(); + private final SparseArray> mSparseArray = new SparseArray<>(); + + public void append(int key, E value) { + removeUnreachableValues(); + mSparseArray.append(key, new WeakReferenceWithId(value, mRefQueue, key)); + } + + public void remove(int key) { + removeUnreachableValues(); + mSparseArray.remove(key); + } + + public E get(int key) { + removeUnreachableValues(); + WeakReferenceWithId ref = mSparseArray.get(key); + return ref != null ? ref.get() : null; + } + + private void removeUnreachableValues() { + for (Reference ref = mRefQueue.poll(); ref != null; ref = mRefQueue.poll()) { + mSparseArray.remove(((WeakReferenceWithId) ref).mId); + } + } + + private static class WeakReferenceWithId extends WeakReference { + + final int mId; + + WeakReferenceWithId(E referent, ReferenceQueue q, int id) { + super(referent, q); + mId = id; + } + } +} +