From 099459377a737d885bbd8ac4d52e6884a103b1c7 Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Tue, 20 Sep 2011 14:22:40 -0700 Subject: [PATCH] Clean up bitmaps when necessary in the widget tray to prevent likelihood of OOM. (Bug: 5348390) - Removing some old code to use software layers when rendering widget preview metadata Change-Id: I0db3daf7d1223e81dac6c901647acbe2ff490c6e --- .../launcher2/AppsCustomizePagedView.java | 105 ++++++++++++------ .../android/launcher2/PagedViewWidget.java | 18 ++- 2 files changed, 86 insertions(+), 37 deletions(-) diff --git a/src/com/android/launcher2/AppsCustomizePagedView.java b/src/com/android/launcher2/AppsCustomizePagedView.java index 6493e973e2..560c3c7172 100644 --- a/src/com/android/launcher2/AppsCustomizePagedView.java +++ b/src/com/android/launcher2/AppsCustomizePagedView.java @@ -96,6 +96,25 @@ class AsyncTaskPageData { doInBackgroundCallback = bgR; postExecuteCallback = postR; } + void cleanup(boolean cancelled) { + // Clean up any references to source/generated bitmaps + if (sourceImages != null) { + if (cancelled) { + for (Bitmap b : sourceImages) { + b.recycle(); + } + } + sourceImages.clear(); + } + if (generatedImages != null) { + if (cancelled) { + for (Bitmap b : generatedImages) { + b.recycle(); + } + } + generatedImages.clear(); + } + } int page; ArrayList items; ArrayList sourceImages; @@ -746,21 +765,31 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen @Override public void run(AppsCustomizeAsyncTask task, AsyncTaskPageData data) { try { - Thread.sleep(sleepMs); - } catch (Exception e) {} - loadWidgetPreviewsInBackground(task, data); + try { + Thread.sleep(sleepMs); + } catch (Exception e) {} + loadWidgetPreviewsInBackground(task, data); + } finally { + if (task.isCancelled()) { + data.cleanup(true); + } + } } }, new AsyncTaskCallback() { @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); + try { + mRunningTasks.remove(task); + if (task.isCancelled()) return; + if (task.page > getPageCount()) return; + if (task.pageContentType != mContentType) return; + onSyncWidgetPageItems(data); + } finally { + data.cleanup(task.isCancelled()); + } } - }); + }); // Ensure that the task is appropriately prioritized and runs in parallel AppsCustomizeAsyncTask t = new AppsCustomizeAsyncTask(page, mContentType, @@ -790,40 +819,50 @@ public class AppsCustomizePagedView extends PagedViewWithDraggableItems implemen new AsyncTaskCallback() { @Override public void run(AppsCustomizeAsyncTask task, AsyncTaskPageData data) { - // Ensure that this task starts running at the correct priority - task.syncThreadPriority(); - - ArrayList images = data.generatedImages; - ArrayList srcImages = data.sourceImages; - int count = srcImages.size(); - Canvas c = new Canvas(); - for (int i = 0; i < count && !task.isCancelled(); ++i) { - // Before work on each item, ensure that this task is running at the correct - // priority + try { + // Ensure that this task starts running at the correct priority task.syncThreadPriority(); - Bitmap b = srcImages.get(i); - Bitmap outline = Bitmap.createBitmap(b.getWidth(), b.getHeight(), - Bitmap.Config.ARGB_8888); + ArrayList images = data.generatedImages; + ArrayList srcImages = data.sourceImages; + int count = srcImages.size(); + Canvas c = new Canvas(); + for (int i = 0; i < count && !task.isCancelled(); ++i) { + // Before work on each item, ensure that this task is running at the correct + // priority + task.syncThreadPriority(); - c.setBitmap(outline); - c.save(); - c.drawBitmap(b, 0, 0, null); - c.restore(); - c.setBitmap(null); + Bitmap b = srcImages.get(i); + Bitmap outline = Bitmap.createBitmap(b.getWidth(), b.getHeight(), + Bitmap.Config.ARGB_8888); - images.add(outline); + c.setBitmap(outline); + c.save(); + c.drawBitmap(b, 0, 0, null); + c.restore(); + c.setBitmap(null); + + images.add(outline); + } + } finally { + if (task.isCancelled()) { + data.cleanup(true); + } } } }, new AsyncTaskCallback() { @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); + try { + mRunningTasks.remove(task); + if (task.isCancelled()) return; + if (task.page > getPageCount()) return; + if (task.pageContentType != mContentType) return; + onHolographicPageItemsLoaded(data); + } finally { + data.cleanup(task.isCancelled()); + } } }); diff --git a/src/com/android/launcher2/PagedViewWidget.java b/src/com/android/launcher2/PagedViewWidget.java index 053c2ea1a3..4e06570fce 100644 --- a/src/com/android/launcher2/PagedViewWidget.java +++ b/src/com/android/launcher2/PagedViewWidget.java @@ -96,6 +96,20 @@ public class PagedViewWidget extends LinearLayout implements Checkable { setClipToPadding(false); } + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + + final ImageView image = (ImageView) findViewById(R.id.widget_preview); + if (image != null) { + FastBitmapDrawable preview = (FastBitmapDrawable) image.getDrawable(); + if (preview != null && preview.getBitmap() != null) { + preview.getBitmap().recycle(); + } + image.setImageDrawable(null); + } + } + public void applyFromAppWidgetProviderInfo(AppWidgetProviderInfo info, FastBitmapDrawable preview, int maxWidth, int[] cellSpan, HolographicOutlineHelper holoOutlineHelper) { @@ -109,11 +123,9 @@ public class PagedViewWidget extends LinearLayout implements Checkable { mPreviewImageView = image; final TextView name = (TextView) findViewById(R.id.widget_name); name.setText(info.label); - name.setLayerType(View.LAYER_TYPE_SOFTWARE, null); final TextView dims = (TextView) findViewById(R.id.widget_dims); if (dims != null) { dims.setText(String.format(mDimensionsFormatString, cellSpan[0], cellSpan[1])); - dims.setLayerType(View.LAYER_TYPE_SOFTWARE, null); } } @@ -127,11 +139,9 @@ public class PagedViewWidget extends LinearLayout implements Checkable { mPreviewImageView = image; final TextView name = (TextView) findViewById(R.id.widget_name); name.setText(label); - name.setLayerType(View.LAYER_TYPE_SOFTWARE, null); final TextView dims = (TextView) findViewById(R.id.widget_dims); if (dims != null) { dims.setText(String.format(mDimensionsFormatString, 1, 1)); - dims.setLayerType(View.LAYER_TYPE_SOFTWARE, null); } }