From 9926272f32868c858b24b45e048210cf3515741e Mon Sep 17 00:00:00 2001 From: Michael Jurka Date: Tue, 17 Sep 2013 14:18:04 +0200 Subject: Reduce memory usage of default thumbnail Bug: 10639174 Change-Id: I2b7f3844e77427d2327a7d89c63e4f3b0d890bc0 --- .../recent/ColorDrawableWithDimensions.java | 40 ++++++++++++++++++++++ .../android/systemui/recent/RecentTasksLoader.java | 18 +++++----- .../src/com/android/systemui/recent/Recents.java | 12 ++++++- .../android/systemui/recent/RecentsPanelView.java | 40 ++++++++++++---------- .../android/systemui/recent/TaskDescription.java | 6 ++-- 5 files changed, 84 insertions(+), 32 deletions(-) create mode 100644 packages/SystemUI/src/com/android/systemui/recent/ColorDrawableWithDimensions.java (limited to 'packages/SystemUI/src') diff --git a/packages/SystemUI/src/com/android/systemui/recent/ColorDrawableWithDimensions.java b/packages/SystemUI/src/com/android/systemui/recent/ColorDrawableWithDimensions.java new file mode 100644 index 0000000..b4d3edd --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/recent/ColorDrawableWithDimensions.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.recent; + +import android.graphics.drawable.ColorDrawable; + +public class ColorDrawableWithDimensions extends ColorDrawable { + private int mWidth; + private int mHeight; + + public ColorDrawableWithDimensions(int color, int width, int height) { + super(color); + mWidth = width; + mHeight = height; + } + + @Override + public int getIntrinsicWidth() { + return mWidth; + } + + @Override + public int getIntrinsicHeight() { + return mHeight; + } +} diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentTasksLoader.java b/packages/SystemUI/src/com/android/systemui/recent/RecentTasksLoader.java index 8b2cd3f..c714d8b 100644 --- a/packages/SystemUI/src/com/android/systemui/recent/RecentTasksLoader.java +++ b/packages/SystemUI/src/com/android/systemui/recent/RecentTasksLoader.java @@ -25,7 +25,7 @@ import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.res.Resources; import android.graphics.Bitmap; -import android.graphics.Canvas; +import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.os.AsyncTask; import android.os.Handler; @@ -62,8 +62,8 @@ public class RecentTasksLoader implements View.OnTouchListener { private Handler mHandler; private int mIconDpi; - private Bitmap mDefaultThumbnailBackground; - private Bitmap mDefaultIconBackground; + private ColorDrawableWithDimensions mDefaultThumbnailBackground; + private ColorDrawableWithDimensions mDefaultIconBackground; private int mNumTasksInFirstScreenful = Integer.MAX_VALUE; private boolean mFirstScreenful; @@ -100,7 +100,7 @@ public class RecentTasksLoader implements View.OnTouchListener { // Render default icon (just a blank image) int defaultIconSize = res.getDimensionPixelSize(com.android.internal.R.dimen.app_icon_size); int iconSize = (int) (defaultIconSize * mIconDpi / res.getDisplayMetrics().densityDpi); - mDefaultIconBackground = Bitmap.createBitmap(iconSize, iconSize, Bitmap.Config.ARGB_8888); + mDefaultIconBackground = new ColorDrawableWithDimensions(0x00000000, iconSize, iconSize); // Render the default thumbnail background int thumbnailWidth = @@ -110,9 +110,7 @@ public class RecentTasksLoader implements View.OnTouchListener { int color = res.getColor(R.drawable.status_bar_recents_app_thumbnail_background); mDefaultThumbnailBackground = - Bitmap.createBitmap(thumbnailWidth, thumbnailHeight, Bitmap.Config.ARGB_8888); - Canvas c = new Canvas(mDefaultThumbnailBackground); - c.drawColor(color); + new ColorDrawableWithDimensions(color, thumbnailWidth, thumbnailHeight); } public void setRecentsPanel(RecentsPanelView newRecentsPanel, RecentsPanelView caller) { @@ -125,11 +123,11 @@ public class RecentTasksLoader implements View.OnTouchListener { } } - public Bitmap getDefaultThumbnail() { + public Drawable getDefaultThumbnail() { return mDefaultThumbnailBackground; } - public Bitmap getDefaultIcon() { + public Drawable getDefaultIcon() { return mDefaultIconBackground; } @@ -199,7 +197,7 @@ public class RecentTasksLoader implements View.OnTouchListener { + td + ": " + thumbnail); synchronized (td) { if (thumbnail != null) { - td.setThumbnail(thumbnail); + td.setThumbnail(new BitmapDrawable(mContext.getResources(), thumbnail)); } else { td.setThumbnail(mDefaultThumbnailBackground); } diff --git a/packages/SystemUI/src/com/android/systemui/recent/Recents.java b/packages/SystemUI/src/com/android/systemui/recent/Recents.java index f51e34b..f5670e1 100644 --- a/packages/SystemUI/src/com/android/systemui/recent/Recents.java +++ b/packages/SystemUI/src/com/android/systemui/recent/Recents.java @@ -22,7 +22,10 @@ import android.content.Intent; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Bitmap; +import android.graphics.Canvas; import android.graphics.Paint; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; import android.os.UserHandle; import android.util.DisplayMetrics; import android.util.Log; @@ -68,7 +71,14 @@ public class Recents extends SystemUI implements RecentsComponent { } } else { - Bitmap first = firstTask.getThumbnail(); + Bitmap first = null; + if (firstTask.getThumbnail() instanceof BitmapDrawable) { + first = ((BitmapDrawable) firstTask.getThumbnail()).getBitmap(); + } else { + first = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); + Drawable d = RecentTasksLoader.getInstance(mContext).getDefaultThumbnail(); + d.draw(new Canvas(first)); + } final Resources res = mContext.getResources(); float thumbWidth = res diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java index 5ebd11e..918f4a4 100644 --- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java @@ -113,7 +113,7 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener /* package */ final static class ViewHolder { View thumbnailView; ImageView thumbnailViewImage; - Bitmap thumbnailViewImageBitmap; + Drawable thumbnailViewDrawable; ImageView iconView; TextView labelView; TextView descriptionView; @@ -151,7 +151,7 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener // the thumbnail later (if they both have the same dimensions) updateThumbnail(holder, mRecentTasksLoader.getDefaultThumbnail(), false, false); holder.iconView = (ImageView) convertView.findViewById(R.id.app_icon); - holder.iconView.setImageBitmap(mRecentTasksLoader.getDefaultIcon()); + holder.iconView.setImageDrawable(mRecentTasksLoader.getDefaultIcon()); holder.labelView = (TextView) convertView.findViewById(R.id.app_label); holder.calloutLine = convertView.findViewById(R.id.recents_callout_line); holder.descriptionView = (TextView) convertView.findViewById(R.id.app_description); @@ -227,7 +227,7 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener public void recycleView(View v) { ViewHolder holder = (ViewHolder) v.getTag(); updateThumbnail(holder, mRecentTasksLoader.getDefaultThumbnail(), false, false); - holder.iconView.setImageBitmap(mRecentTasksLoader.getDefaultIcon()); + holder.iconView.setImageDrawable(mRecentTasksLoader.getDefaultIcon()); holder.iconView.setVisibility(INVISIBLE); holder.iconView.animate().cancel(); holder.labelView.setText(null); @@ -488,23 +488,23 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener } } - private void updateThumbnail(ViewHolder h, Bitmap thumbnail, boolean show, boolean anim) { + private void updateThumbnail(ViewHolder h, Drawable thumbnail, boolean show, boolean anim) { if (thumbnail != null) { // Should remove the default image in the frame // that this now covers, to improve scrolling speed. // That can't be done until the anim is complete though. - h.thumbnailViewImage.setImageBitmap(thumbnail); + h.thumbnailViewImage.setImageDrawable(thumbnail); // scale the image to fill the full width of the ImageView. do this only if // we haven't set a bitmap before, or if the bitmap size has changed - if (h.thumbnailViewImageBitmap == null || - h.thumbnailViewImageBitmap.getWidth() != thumbnail.getWidth() || - h.thumbnailViewImageBitmap.getHeight() != thumbnail.getHeight()) { + if (h.thumbnailViewDrawable == null || + h.thumbnailViewDrawable.getIntrinsicWidth() != thumbnail.getIntrinsicWidth() || + h.thumbnailViewDrawable.getIntrinsicHeight() != thumbnail.getIntrinsicHeight()) { if (mFitThumbnailToXY) { h.thumbnailViewImage.setScaleType(ScaleType.FIT_XY); } else { Matrix scaleMatrix = new Matrix(); - float scale = mThumbnailWidth / (float) thumbnail.getWidth(); + float scale = mThumbnailWidth / (float) thumbnail.getIntrinsicWidth(); scaleMatrix.setScale(scale, scale); h.thumbnailViewImage.setScaleType(ScaleType.MATRIX); h.thumbnailViewImage.setImageMatrix(scaleMatrix); @@ -517,7 +517,7 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener } h.thumbnailView.setVisibility(View.VISIBLE); } - h.thumbnailViewImageBitmap = thumbnail; + h.thumbnailViewDrawable = thumbnail; } } @@ -663,20 +663,24 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener } public void handleOnClick(View view) { - ViewHolder holder = (ViewHolder)view.getTag(); + ViewHolder holder = (ViewHolder) view.getTag(); TaskDescription ad = holder.taskDescription; final Context context = view.getContext(); final ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); - Bitmap bm = holder.thumbnailViewImageBitmap; - boolean usingDrawingCache; - if (bm.getWidth() == holder.thumbnailViewImage.getWidth() && - bm.getHeight() == holder.thumbnailViewImage.getHeight()) { - usingDrawingCache = false; - } else { + + Bitmap bm = null; + boolean usingDrawingCache = true; + if (holder.thumbnailViewDrawable instanceof BitmapDrawable) { + bm = ((BitmapDrawable) holder.thumbnailViewDrawable).getBitmap(); + if (bm.getWidth() == holder.thumbnailViewImage.getWidth() && + bm.getHeight() == holder.thumbnailViewImage.getHeight()) { + usingDrawingCache = false; + } + } + if (usingDrawingCache) { holder.thumbnailViewImage.setDrawingCacheEnabled(true); bm = holder.thumbnailViewImage.getDrawingCache(); - usingDrawingCache = true; } Bundle opts = (bm == null) ? null : diff --git a/packages/SystemUI/src/com/android/systemui/recent/TaskDescription.java b/packages/SystemUI/src/com/android/systemui/recent/TaskDescription.java index 7e979b7..2bc2821 100644 --- a/packages/SystemUI/src/com/android/systemui/recent/TaskDescription.java +++ b/packages/SystemUI/src/com/android/systemui/recent/TaskDescription.java @@ -29,7 +29,7 @@ public final class TaskDescription { final String packageName; // used to override animations (see onClick()) final CharSequence description; - private Bitmap mThumbnail; // generated by Activity.onCreateThumbnail() + private Drawable mThumbnail; // generated by Activity.onCreateThumbnail() private Drawable mIcon; // application package icon private CharSequence mLabel; // application package label private boolean mLoaded; @@ -85,11 +85,11 @@ public final class TaskDescription { mIcon = icon; } - public void setThumbnail(Bitmap thumbnail) { + public void setThumbnail(Drawable thumbnail) { mThumbnail = thumbnail; } - public Bitmap getThumbnail() { + public Drawable getThumbnail() { return mThumbnail; } } -- cgit v1.1