Skip to content

Commit 7db82ac

Browse files
committed
Fix leaky view tags
The implementation of the method View#setTag(int, Object) stored tag objects as entries in a static WeakHashMap associated with the View as a key. This was problematic for any tag object that stored a hard reference back to the View the tag was placed on, as it would cause the WeakReference key to never be collected and the entry to persist forever. This was particularly nasty if an app used a keyed tag to store a ViewHolder object referencing child views for use in the Adapter implementaion for an AdapterView, since child views will always have hard references leading back to the parent. Change-Id: Ia17840a301ba0e0c928861405388fb2f625dac2c
1 parent e94d950 commit 7db82ac

1 file changed

Lines changed: 8 additions & 33 deletions

File tree

core/java/android/view/View.java

Lines changed: 8 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,6 @@
8181
import java.util.ArrayList;
8282
import java.util.Arrays;
8383
import java.util.Locale;
84-
import java.util.WeakHashMap;
8584
import java.util.concurrent.CopyOnWriteArrayList;
8685

8786
/**
@@ -1497,12 +1496,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
14971496
/**
14981497
* Map used to store views' tags.
14991498
*/
1500-
private static WeakHashMap<View, SparseArray<Object>> sTags;
1501-
1502-
/**
1503-
* Lock used to access sTags.
1504-
*/
1505-
private static final Object sTagsLock = new Object();
1499+
private SparseArray<Object> mKeyedTags;
15061500

15071501
/**
15081502
* The next available accessiiblity id.
@@ -12236,14 +12230,7 @@ public void setTag(final Object tag) {
1223612230
* @see #getTag()
1223712231
*/
1223812232
public Object getTag(int key) {
12239-
SparseArray<Object> tags = null;
12240-
synchronized (sTagsLock) {
12241-
if (sTags != null) {
12242-
tags = sTags.get(this);
12243-
}
12244-
}
12245-
12246-
if (tags != null) return tags.get(key);
12233+
if (mKeyedTags != null) return mKeyedTags.get(key);
1224712234
return null;
1224812235
}
1224912236

@@ -12276,7 +12263,7 @@ public void setTag(int key, final Object tag) {
1227612263
+ "resource id.");
1227712264
}
1227812265

12279-
setTagInternal(this, key, tag);
12266+
setKeyedTag(this, key, tag);
1228012267
}
1228112268

1228212269
/**
@@ -12291,27 +12278,15 @@ public void setTagInternal(int key, Object tag) {
1229112278
+ "resource id.");
1229212279
}
1229312280

12294-
setTagInternal(this, key, tag);
12281+
setKeyedTag(this, key, tag);
1229512282
}
1229612283

12297-
private static void setTagInternal(View view, int key, Object tag) {
12298-
SparseArray<Object> tags = null;
12299-
synchronized (sTagsLock) {
12300-
if (sTags == null) {
12301-
sTags = new WeakHashMap<View, SparseArray<Object>>();
12302-
} else {
12303-
tags = sTags.get(view);
12304-
}
12305-
}
12306-
12307-
if (tags == null) {
12308-
tags = new SparseArray<Object>(2);
12309-
synchronized (sTagsLock) {
12310-
sTags.put(view, tags);
12311-
}
12284+
private void setKeyedTag(View view, int key, Object tag) {
12285+
if (mKeyedTags == null) {
12286+
mKeyedTags = new SparseArray<Object>();
1231212287
}
1231312288

12314-
tags.put(key, tag);
12289+
mKeyedTags.put(key, tag);
1231512290
}
1231612291

1231712292
/**

0 commit comments

Comments
 (0)