From 7db82acd8151684a886d4725ddf2790ef3a2f80e Mon Sep 17 00:00:00 2001 From: Adam Powell Date: Thu, 22 Sep 2011 19:44:04 -0700 Subject: [PATCH] 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 --- core/java/android/view/View.java | 41 +++++++------------------------- 1 file changed, 8 insertions(+), 33 deletions(-) diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index f993160f1829f..46cda2dfc4a5b 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -81,7 +81,6 @@ import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.Locale; -import java.util.WeakHashMap; import java.util.concurrent.CopyOnWriteArrayList; /** @@ -1497,12 +1496,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal /** * Map used to store views' tags. */ - private static WeakHashMap> sTags; - - /** - * Lock used to access sTags. - */ - private static final Object sTagsLock = new Object(); + private SparseArray mKeyedTags; /** * The next available accessiiblity id. @@ -12236,14 +12230,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal * @see #getTag() */ public Object getTag(int key) { - SparseArray tags = null; - synchronized (sTagsLock) { - if (sTags != null) { - tags = sTags.get(this); - } - } - - if (tags != null) return tags.get(key); + if (mKeyedTags != null) return mKeyedTags.get(key); return null; } @@ -12276,7 +12263,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal + "resource id."); } - setTagInternal(this, key, tag); + setKeyedTag(this, key, tag); } /** @@ -12291,27 +12278,15 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal + "resource id."); } - setTagInternal(this, key, tag); + setKeyedTag(this, key, tag); } - private static void setTagInternal(View view, int key, Object tag) { - SparseArray tags = null; - synchronized (sTagsLock) { - if (sTags == null) { - sTags = new WeakHashMap>(); - } else { - tags = sTags.get(view); - } + private void setKeyedTag(View view, int key, Object tag) { + if (mKeyedTags == null) { + mKeyedTags = new SparseArray(); } - if (tags == null) { - tags = new SparseArray(2); - synchronized (sTagsLock) { - sTags.put(view, tags); - } - } - - tags.put(key, tag); + mKeyedTags.put(key, tag); } /**