diff options
author | Adam Cohen <adamcohen@google.com> | 2011-07-11 17:53:37 -0700 |
---|---|---|
committer | Adam Cohen <adamcohen@google.com> | 2011-07-11 18:37:16 -0700 |
commit | 4eac29a80b9a73465c8de54f1caec2a8098a73c6 (patch) | |
tree | ad6e6a7c9ec5da36462a04d329ef5a00b9fb10f1 | |
parent | 51e95039ac40f94de024413a6e7fb1e18d41ef19 (diff) | |
download | android_packages_apps_Trebuchet-4eac29a80b9a73465c8de54f1caec2a8098a73c6.tar.gz android_packages_apps_Trebuchet-4eac29a80b9a73465c8de54f1caec2a8098a73c6.tar.bz2 android_packages_apps_Trebuchet-4eac29a80b9a73465c8de54f1caec2a8098a73c6.zip |
Fixing bug 5011917 - clearing refernce to old folders from FolderInfo
-> Also, ensured that unbind() gets called on all ItemInfos on rotate
Change-Id: I869b68fcae5c66702ec204596f5ecabdc7a32df7
-rw-r--r-- | src/com/android/launcher2/Folder.java | 12 | ||||
-rw-r--r-- | src/com/android/launcher2/FolderIcon.java | 1 | ||||
-rw-r--r-- | src/com/android/launcher2/FolderInfo.java | 6 | ||||
-rw-r--r-- | src/com/android/launcher2/ItemInfo.java | 8 | ||||
-rw-r--r-- | src/com/android/launcher2/Launcher.java | 23 | ||||
-rw-r--r-- | src/com/android/launcher2/LauncherModel.java | 36 |
6 files changed, 43 insertions, 43 deletions
diff --git a/src/com/android/launcher2/Folder.java b/src/com/android/launcher2/Folder.java index 788d4b9bc..78df80fb3 100644 --- a/src/com/android/launcher2/Folder.java +++ b/src/com/android/launcher2/Folder.java @@ -54,14 +54,12 @@ import java.util.ArrayList; public class Folder extends LinearLayout implements DragSource, View.OnClickListener, View.OnLongClickListener, DropTarget, FolderListener, TextView.OnEditorActionListener { - protected DragController mDragController; + private static final String TAG = "Launcher.Folder"; + protected DragController mDragController; protected Launcher mLauncher; - protected FolderInfo mInfo; - private static final String TAG = "Launcher.Folder"; - static final int STATE_NONE = -1; static final int STATE_SMALL = 0; static final int STATE_ANIMATING = 1; @@ -132,6 +130,8 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList if (sHintText == null) { sHintText = res.getString(R.string.folder_hint_text); } + + mLauncher = (Launcher) context; } @Override @@ -286,10 +286,6 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList mDragController = dragController; } - void setLauncher(Launcher launcher) { - mLauncher = launcher; - } - void setFolderIcon(FolderIcon icon) { mFolderIcon = icon; } diff --git a/src/com/android/launcher2/FolderIcon.java b/src/com/android/launcher2/FolderIcon.java index 283c2954f..952916d5f 100644 --- a/src/com/android/launcher2/FolderIcon.java +++ b/src/com/android/launcher2/FolderIcon.java @@ -127,7 +127,6 @@ public class FolderIcon extends LinearLayout implements FolderListener { Folder folder = Folder.fromXml(launcher); folder.setDragController(launcher.getDragController()); - folder.setLauncher(launcher); folder.setFolderIcon(icon); folder.bind(folderInfo); icon.mFolder = folder; diff --git a/src/com/android/launcher2/FolderInfo.java b/src/com/android/launcher2/FolderInfo.java index b5b5b29c1..3ae31d278 100644 --- a/src/com/android/launcher2/FolderInfo.java +++ b/src/com/android/launcher2/FolderInfo.java @@ -99,6 +99,12 @@ class FolderInfo extends ItemInfo { } } + @Override + void unbind() { + super.unbind(); + listeners.clear(); + } + interface FolderListener { public void onAdd(ShortcutInfo item); public void onRemove(ShortcutInfo item); diff --git a/src/com/android/launcher2/ItemInfo.java b/src/com/android/launcher2/ItemInfo.java index 3a1c29a45..8d4662495 100644 --- a/src/com/android/launcher2/ItemInfo.java +++ b/src/com/android/launcher2/ItemInfo.java @@ -144,7 +144,13 @@ class ItemInfo { values.put(LauncherSettings.Favorites.ICON, data); } } - + + /** + * It is very important that sub-classes implement this if they contain any references + * to the activity (anything in the view hierarchy etc.). If not, leaks can result since + * ItemInfo objects persist across rotation and can hence leak by holding stale references + * to the old view hierarchy / activity. + */ void unbind() { } diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java index 33a86a95b..5e500ba76 100644 --- a/src/com/android/launcher2/Launcher.java +++ b/src/com/android/launcher2/Launcher.java @@ -221,8 +221,6 @@ public final class Launcher extends Activity private static LocaleConfiguration sLocaleConfiguration = null; - private ArrayList<ItemInfo> mDesktopItems = new ArrayList<ItemInfo>(); - private static HashMap<Long, FolderInfo> sFolders = new HashMap<Long, FolderInfo>(); // Hotseats (quick-launch icons next to AllApps) @@ -1098,8 +1096,6 @@ public final class Launcher extends Activity screen, cellXY[0], cellXY[1], false); if (!mRestoring) { - mDesktopItems.add(launcherInfo); - // Perform actual inflation because we're live launcherInfo.hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo); @@ -1228,7 +1224,6 @@ public final class Launcher extends Activity } public void removeAppWidget(LauncherAppWidgetInfo launcherInfo) { - mDesktopItems.remove(launcherInfo); removeWidgetToAutoAdvance(launcherInfo.hostView); launcherInfo.hostView = null; } @@ -1359,7 +1354,7 @@ public final class Launcher extends Activity TextKeyListener.getInstance().release(); - unbindDesktopItems(); + unbindWorkspaceItems(); getContentResolver().unregisterContentObserver(mWidgetObserver); unregisterReceiver(mCloseSystemDialogsReceiver); @@ -1743,11 +1738,8 @@ public final class Launcher extends Activity * Go through the and disconnect any of the callbacks in the drawables and the views or we * leak the previous Home screen on orientation change. */ - private void unbindDesktopItems() { - for (ItemInfo item: mDesktopItems) { - item.unbind(); - } - mDesktopItems.clear(); + private void unbindWorkspaceItems() { + LauncherModel.unbindWorkspaceItems(); } /** @@ -3016,9 +3008,8 @@ public final class Launcher extends Activity }); } - // This wasn't being called before which resulted in a leak of AppWidgetHostViews (through - // mDesktopItems -> AppWidgetInfo -> hostView). - unbindDesktopItems(); + // This wasn't being called before which resulted in a leak of AppWidgetHostViews + unbindWorkspaceItems(); } /** @@ -3034,7 +3025,6 @@ public final class Launcher extends Activity for (int i=start; i<end; i++) { final ItemInfo item = shortcuts.get(i); - mDesktopItems.add(item); switch (item.itemType) { case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION: case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT: @@ -3096,8 +3086,6 @@ public final class Launcher extends Activity workspace.requestLayout(); - mDesktopItems.add(item); - if (DEBUG_WIDGETS) { Log.d(TAG, "bound widget id="+item.appWidgetId+" in " + (SystemClock.uptimeMillis()-start) + "ms"); @@ -3269,7 +3257,6 @@ public final class Launcher extends Activity Log.d(TAG, "mRestoring=" + mRestoring); Log.d(TAG, "mWaitingForResult=" + mWaitingForResult); Log.d(TAG, "mSavedInstanceState=" + mSavedInstanceState); - Log.d(TAG, "mDesktopItems.size=" + mDesktopItems.size()); Log.d(TAG, "sFolders.size=" + sFolders.size()); mModel.dumpState(); diff --git a/src/com/android/launcher2/LauncherModel.java b/src/com/android/launcher2/LauncherModel.java index 64b38c0e3..ec629d03f 100644 --- a/src/com/android/launcher2/LauncherModel.java +++ b/src/com/android/launcher2/LauncherModel.java @@ -98,7 +98,7 @@ public class LauncherModel extends BroadcastReceiver { // sItems is passed to bindItems, which expects a list of all folders and shortcuts created by // LauncherModel that are directly on the home screen (however, no widgets or shortcuts // within folders). - static final ArrayList<ItemInfo> sItems = new ArrayList<ItemInfo>(); + static final ArrayList<ItemInfo> sWorkspaceItems = new ArrayList<ItemInfo>(); // sAppWidgets is all LauncherAppWidgetInfo created by LauncherModel. Passed to bindAppWidget() static final ArrayList<LauncherAppWidgetInfo> sAppWidgets = @@ -148,6 +148,12 @@ public class LauncherModel extends BroadcastReceiver { return Bitmap.createBitmap(mDefaultIcon); } + public static void unbindWorkspaceItems() { + for (ItemInfo item: sWorkspaceItems) { + item.unbind(); + } + } + /** * Adds an item to the DB if it was not created previously, or move it to a new * <container, screen, cellX, cellY> @@ -197,11 +203,11 @@ public class LauncherModel extends BroadcastReceiver { // as in Workspace.onDrop. Here, we just add/remove them from the list of items // that are on the desktop, as appropriate if (modelItem.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) { - if (!sItems.contains(modelItem)) { - sItems.add(modelItem); + if (!sWorkspaceItems.contains(modelItem)) { + sWorkspaceItems.add(modelItem); } } else { - sItems.remove(modelItem); + sWorkspaceItems.remove(modelItem); } } }); @@ -374,13 +380,13 @@ public class LauncherModel extends BroadcastReceiver { case LauncherSettings.Favorites.ITEM_TYPE_FOLDER: sFolders.put(item.id, (FolderInfo) item); if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) { - sItems.add(item); + sWorkspaceItems.add(item); } break; case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION: case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT: if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) { - sItems.add(item); + sWorkspaceItems.add(item); } break; case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET: @@ -456,11 +462,11 @@ public class LauncherModel extends BroadcastReceiver { switch (item.itemType) { case LauncherSettings.Favorites.ITEM_TYPE_FOLDER: sFolders.remove(item.id); - sItems.remove(item); + sWorkspaceItems.remove(item); break; case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION: case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT: - sItems.remove(item); + sWorkspaceItems.remove(item); break; case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET: sAppWidgets.remove((LauncherAppWidgetInfo) item); @@ -482,7 +488,7 @@ public class LauncherModel extends BroadcastReceiver { cr.delete(LauncherSettings.Favorites.getContentUri(info.id, false), null, null); sItemsIdMap.remove(info.id); sFolders.remove(info.id); - sItems.remove(info); + sWorkspaceItems.remove(info); cr.delete(LauncherSettings.Favorites.CONTENT_URI, LauncherSettings.Favorites.CONTAINER + "=" + info.id, null); @@ -819,7 +825,7 @@ public class LauncherModel extends BroadcastReceiver { final AppWidgetManager widgets = AppWidgetManager.getInstance(context); final boolean isSafeMode = manager.isSafeMode(); - sItems.clear(); + sWorkspaceItems.clear(); sAppWidgets.clear(); sFolders.clear(); sItemsIdMap.clear(); @@ -911,7 +917,7 @@ public class LauncherModel extends BroadcastReceiver { switch (container) { case LauncherSettings.Favorites.CONTAINER_DESKTOP: - sItems.add(info); + sWorkspaceItems.add(info); break; default: // Item is in a user folder @@ -955,7 +961,7 @@ public class LauncherModel extends BroadcastReceiver { } switch (container) { case LauncherSettings.Favorites.CONTAINER_DESKTOP: - sItems.add(folderInfo); + sWorkspaceItems.add(folderInfo); break; } @@ -1072,7 +1078,7 @@ public class LauncherModel extends BroadcastReceiver { } }); // Add the items to the workspace. - N = sItems.size(); + N = sWorkspaceItems.size(); for (int i=0; i<N; i+=ITEMS_CHUNK) { final int start = i; final int chunkSize = (i+ITEMS_CHUNK <= N) ? ITEMS_CHUNK : (N-i); @@ -1080,7 +1086,7 @@ public class LauncherModel extends BroadcastReceiver { public void run() { Callbacks callbacks = tryGetCallbacks(oldCallbacks); if (callbacks != null) { - callbacks.bindItems(sItems, start, start+chunkSize); + callbacks.bindItems(sWorkspaceItems, start, start+chunkSize); } } }); @@ -1317,7 +1323,7 @@ public class LauncherModel extends BroadcastReceiver { Log.d(TAG, "mLoaderTask.mIsLaunching=" + mIsLaunching); Log.d(TAG, "mLoaderTask.mStopped=" + mStopped); Log.d(TAG, "mLoaderTask.mLoadAndBindStepFinished=" + mLoadAndBindStepFinished); - Log.d(TAG, "mItems size=" + sItems.size()); + Log.d(TAG, "mItems size=" + sWorkspaceItems.size()); } } |