diff options
author | Winson Chung <winsonc@google.com> | 2011-09-02 11:45:39 -0700 |
---|---|---|
committer | Winson Chung <winsonc@google.com> | 2011-09-02 17:07:46 -0700 |
commit | 603bcb91a091d0f4512fdfb92d6df3c6f9fa8059 (patch) | |
tree | a7953c5834878c79911e423c9cccc17affe8299d /src | |
parent | 4512637a8a38610282caafe1335a67073dda8224 (diff) | |
download | packages_apps_trebuchet-603bcb91a091d0f4512fdfb92d6df3c6f9fa8059.zip packages_apps_trebuchet-603bcb91a091d0f4512fdfb92d6df3c6f9fa8059.tar.gz packages_apps_trebuchet-603bcb91a091d0f4512fdfb92d6df3c6f9fa8059.tar.bz2 |
Prevent accessing LauncherModel data structures on main thread. (5220358)
Change-Id: Ib9de96abb0ab13ef63b9c594f6982368fd1b614f
Diffstat (limited to 'src')
-rw-r--r-- | src/com/android/launcher2/Launcher.java | 7 | ||||
-rw-r--r-- | src/com/android/launcher2/LauncherModel.java | 41 |
2 files changed, 37 insertions, 11 deletions
diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java index 637d956..8bbf902 100644 --- a/src/com/android/launcher2/Launcher.java +++ b/src/com/android/launcher2/Launcher.java @@ -1602,7 +1602,9 @@ public final class Launcher extends Activity * leak the previous Home screen on orientation change. */ private void unbindWorkspaceAndHotseatItems() { - LauncherModel.unbindWorkspaceItems(); + if (mModel != null) { + mModel.unbindWorkspaceItems(); + } } /** @@ -2754,9 +2756,6 @@ public final class Launcher extends Activity if (mHotseat != null) { mHotseat.resetLayout(); } - - // This wasn't being called before which resulted in a leak of AppWidgetHostViews - unbindWorkspaceAndHotseatItems(); } /** diff --git a/src/com/android/launcher2/LauncherModel.java b/src/com/android/launcher2/LauncherModel.java index 239970e..ad75798 100644 --- a/src/com/android/launcher2/LauncherModel.java +++ b/src/com/android/launcher2/LauncherModel.java @@ -155,10 +155,31 @@ public class LauncherModel extends BroadcastReceiver { return Bitmap.createBitmap(mDefaultIcon); } - public static void unbindWorkspaceItems() { - for (ItemInfo item: sWorkspaceItems) { - item.unbind(); - } + public void unbindWorkspaceItems() { + sWorker.post(new Runnable() { + @Override + public void run() { + unbindWorkspaceItemsOnMainThread(); + } + }); + } + + /** Unbinds all the sWorkspaceItems on the main thread, and return a copy of sWorkspaceItems + * that is save to reference from the main thread. */ + private ArrayList<ItemInfo> unbindWorkspaceItemsOnMainThread() { + // Ensure that we don't use the same workspace items data structure on the main thread + // by making a copy of workspace items first. + final ArrayList<ItemInfo> workspaceItems = new ArrayList<ItemInfo>(sWorkspaceItems); + mHandler.post(new Runnable() { + @Override + public void run() { + for (ItemInfo item : workspaceItems) { + item.unbind(); + } + } + }); + + return workspaceItems; } /** @@ -1165,8 +1186,12 @@ public class LauncherModel extends BroadcastReceiver { } } }); + + // Unbind previously bound workspace items to prevent a leak of AppWidgetHostViews. + final ArrayList<ItemInfo> workspaceItems = unbindWorkspaceItemsOnMainThread(); + // Add the items to the workspace. - N = sWorkspaceItems.size(); + N = workspaceItems.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); @@ -1174,16 +1199,18 @@ public class LauncherModel extends BroadcastReceiver { public void run() { Callbacks callbacks = tryGetCallbacks(oldCallbacks); if (callbacks != null) { - callbacks.bindItems(sWorkspaceItems, start, start+chunkSize); + callbacks.bindItems(workspaceItems, start, start+chunkSize); } } }); } + // Ensure that we don't use the same folders data structure on the main thread + final HashMap<Long, FolderInfo> folders = new HashMap<Long, FolderInfo>(sFolders); mHandler.post(new Runnable() { public void run() { Callbacks callbacks = tryGetCallbacks(oldCallbacks); if (callbacks != null) { - callbacks.bindFolders(sFolders); + callbacks.bindFolders(folders); } } }); |