Fixing crash when adding/removing new packages while AppsCustomize is open.

Change-Id: I3bcf1ec811af6f8dddcace65d973ed368e95b4c7
This commit is contained in:
Winson Chung
2011-06-28 14:25:17 -07:00
parent 518eb5dbf5
commit 875de7e160
@@ -67,6 +67,11 @@ interface AsyncTaskCallback {
* The data needed to perform either of the custom AsyncTasks.
*/
class AsyncTaskPageData {
enum Type {
LoadWidgetPreviewData,
LoadHolographicIconsData
}
AsyncTaskPageData(int p, ArrayList<Object> l, ArrayList<Bitmap> si, AsyncTaskCallback bgR,
AsyncTaskCallback postR) {
page = p;
@@ -103,10 +108,11 @@ class AsyncTaskPageData {
* A generic template for an async task used in AppsCustomize.
*/
class AppsCustomizeAsyncTask extends AsyncTask<AsyncTaskPageData, Void, AsyncTaskPageData> {
AppsCustomizeAsyncTask(int p, AppsCustomizePagedView.ContentType t) {
AppsCustomizeAsyncTask(int p, AppsCustomizePagedView.ContentType t, AsyncTaskPageData.Type ty) {
page = p;
pageContentType = t;
threadPriority = Process.THREAD_PRIORITY_DEFAULT;
dataType = ty;
}
@Override
protected AsyncTaskPageData doInBackground(AsyncTaskPageData... params) {
@@ -129,6 +135,7 @@ class AppsCustomizeAsyncTask extends AsyncTask<AsyncTaskPageData, Void, AsyncTas
}
// The page that this async task is associated with
AsyncTaskPageData.Type dataType;
int page;
AppsCustomizePagedView.ContentType pageContentType;
int threadPriority;
@@ -314,6 +321,7 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen
public void onPackagesUpdated() {
// Get the list of widgets and shortcuts
boolean wasEmpty = mWidgets.isEmpty() && mShortcuts.isEmpty();
mWidgets.clear();
mShortcuts.clear();
List<AppWidgetProviderInfo> widgets =
@@ -327,9 +335,13 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen
mWidgets.addAll(widgets);
mShortcuts.addAll(shortcuts);
// The next layout pass will trigger data-ready if both widgets and apps are set, so request
// a layout to do this test and invalidate the page data when ready.
if (testDataReady()) requestLayout();
if (wasEmpty) {
// The next layout pass will trigger data-ready if both widgets and apps are set, so request
// a layout to do this test and invalidate the page data when ready.
if (testDataReady()) requestLayout();
} else {
invalidatePageData();
}
}
@Override
@@ -548,6 +560,7 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen
int startIndex = page * numCells;
int endIndex = Math.min(startIndex + numCells, mApps.size());
PagedViewCellLayout layout = (PagedViewCellLayout) getChildAt(page);
layout.removeAllViewsOnPage();
ArrayList<Object> items = new ArrayList<Object>();
ArrayList<Bitmap> images = new ArrayList<Bitmap>();
@@ -604,7 +617,8 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen
while (iter.hasNext()) {
AppsCustomizeAsyncTask task = (AppsCustomizeAsyncTask) iter.next();
int taskPage = task.page;
if (taskPage < getAssociatedLowerPageBound(mCurrentPage) ||
if ((taskPage == page) ||
taskPage < getAssociatedLowerPageBound(mCurrentPage) ||
taskPage > getAssociatedUpperPageBound(mCurrentPage)) {
task.cancel(false);
iter.remove();
@@ -650,6 +664,7 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen
@Override
public void run(AppsCustomizeAsyncTask task, AsyncTaskPageData data) {
mRunningTasks.remove(task);
if (task.isCancelled()) return;
if (task.page > getPageCount()) return;
if (task.pageContentType != mContentType) return;
onSyncWidgetPageItems(data);
@@ -657,7 +672,8 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen
});
// Ensure that the task is appropriately prioritized and runs in parallel
AppsCustomizeAsyncTask t = new AppsCustomizeAsyncTask(page, mContentType);
AppsCustomizeAsyncTask t = new AppsCustomizeAsyncTask(page, mContentType,
AsyncTaskPageData.Type.LoadWidgetPreviewData);
t.setThreadPriority(getThreadPriorityForPage(page));
t.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, pageData);
mRunningTasks.add(t);
@@ -667,6 +683,18 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen
*/
private void prepareGenerateHoloOutlinesTask(int page, ArrayList<Object> items,
ArrayList<Bitmap> images) {
// Prune old tasks for this page
Iterator<AppsCustomizeAsyncTask> iter = mRunningTasks.iterator();
while (iter.hasNext()) {
AppsCustomizeAsyncTask task = (AppsCustomizeAsyncTask) iter.next();
int taskPage = task.page;
if ((taskPage == page) &&
(task.dataType == AsyncTaskPageData.Type.LoadHolographicIconsData)) {
task.cancel(false);
iter.remove();
}
}
AsyncTaskPageData pageData = new AsyncTaskPageData(page, items, images,
new AsyncTaskCallback() {
@Override
@@ -700,6 +728,7 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen
@Override
public void run(AppsCustomizeAsyncTask task, AsyncTaskPageData data) {
mRunningTasks.remove(task);
if (task.isCancelled()) return;
if (task.page > getPageCount()) return;
if (task.pageContentType != mContentType) return;
onHolographicPageItemsLoaded(data);
@@ -708,7 +737,8 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen
// Ensure that the outline task always runs in the background, serially
AppsCustomizeAsyncTask t =
new AppsCustomizeAsyncTask(page, mContentType);
new AppsCustomizeAsyncTask(page, mContentType,
AsyncTaskPageData.Type.LoadHolographicIconsData);
t.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
t.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, pageData);
mRunningTasks.add(t);
@@ -939,12 +969,14 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen
if (layout instanceof PagedViewCellLayout) {
PagedViewCellLayout cl = (PagedViewCellLayout) layout;
int count = cl.getPageChildCount();
if (count != data.generatedImages.size()) return;
for (int i = 0; i < count; ++i) {
PagedViewIcon icon = (PagedViewIcon) cl.getChildOnPageAt(i);
icon.setHolographicOutline(data.generatedImages.get(i));
}
} else {
int count = layout.getChildCount();
if (count != data.generatedImages.size()) return;
for (int i = 0; i < count; ++i) {
View v = layout.getChildAt(i);
((PagedViewWidget) v).setHolographicOutline(data.generatedImages.get(i));
@@ -955,6 +987,15 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen
@Override
public void syncPages() {
removeAllViews();
// Remove all background asyc tasks if we are loading content anew
Iterator<AppsCustomizeAsyncTask> iter = mRunningTasks.iterator();
while (iter.hasNext()) {
AppsCustomizeAsyncTask task = (AppsCustomizeAsyncTask) iter.next();
task.cancel(false);
iter.remove();
}
switch (mContentType) {
case Applications:
syncAppsPages();
@@ -1037,8 +1078,8 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen
mApps = list;
Collections.sort(mApps, LauncherModel.APP_NAME_COMPARATOR);
// The next layout pass will trigger data-ready if both widgets and apps are set, so request
// a layout to do this test and invalidate the page data when ready.
// The next layout pass will trigger data-ready if both widgets and apps are set, so
// request a layout to do this test and invalidate the page data when ready.
if (testDataReady()) requestLayout();
}
private void addAppsWithoutInvalidate(ArrayList<ApplicationInfo> list) {