am d1544e3f: Merge "Reduce memory usage of default thumbnail" into klp-dev

* commit 'd1544e3f71d35b01e34bbf64720f260c8fa2a7e8':
  Reduce memory usage of default thumbnail
This commit is contained in:
Michael Jurka
2013-09-17 13:42:29 -07:00
committed by Android Git Automerger
5 changed files with 84 additions and 32 deletions

View File

@@ -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;
}
}

View File

@@ -25,7 +25,7 @@ import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo; import android.content.pm.ResolveInfo;
import android.content.res.Resources; import android.content.res.Resources;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.Canvas; import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Handler; import android.os.Handler;
@@ -62,8 +62,8 @@ public class RecentTasksLoader implements View.OnTouchListener {
private Handler mHandler; private Handler mHandler;
private int mIconDpi; private int mIconDpi;
private Bitmap mDefaultThumbnailBackground; private ColorDrawableWithDimensions mDefaultThumbnailBackground;
private Bitmap mDefaultIconBackground; private ColorDrawableWithDimensions mDefaultIconBackground;
private int mNumTasksInFirstScreenful = Integer.MAX_VALUE; private int mNumTasksInFirstScreenful = Integer.MAX_VALUE;
private boolean mFirstScreenful; private boolean mFirstScreenful;
@@ -100,7 +100,7 @@ public class RecentTasksLoader implements View.OnTouchListener {
// Render default icon (just a blank image) // Render default icon (just a blank image)
int defaultIconSize = res.getDimensionPixelSize(com.android.internal.R.dimen.app_icon_size); int defaultIconSize = res.getDimensionPixelSize(com.android.internal.R.dimen.app_icon_size);
int iconSize = (int) (defaultIconSize * mIconDpi / res.getDisplayMetrics().densityDpi); 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 // Render the default thumbnail background
int thumbnailWidth = int thumbnailWidth =
@@ -110,9 +110,7 @@ public class RecentTasksLoader implements View.OnTouchListener {
int color = res.getColor(R.drawable.status_bar_recents_app_thumbnail_background); int color = res.getColor(R.drawable.status_bar_recents_app_thumbnail_background);
mDefaultThumbnailBackground = mDefaultThumbnailBackground =
Bitmap.createBitmap(thumbnailWidth, thumbnailHeight, Bitmap.Config.ARGB_8888); new ColorDrawableWithDimensions(color, thumbnailWidth, thumbnailHeight);
Canvas c = new Canvas(mDefaultThumbnailBackground);
c.drawColor(color);
} }
public void setRecentsPanel(RecentsPanelView newRecentsPanel, RecentsPanelView caller) { 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; return mDefaultThumbnailBackground;
} }
public Bitmap getDefaultIcon() { public Drawable getDefaultIcon() {
return mDefaultIconBackground; return mDefaultIconBackground;
} }
@@ -199,7 +197,7 @@ public class RecentTasksLoader implements View.OnTouchListener {
+ td + ": " + thumbnail); + td + ": " + thumbnail);
synchronized (td) { synchronized (td) {
if (thumbnail != null) { if (thumbnail != null) {
td.setThumbnail(thumbnail); td.setThumbnail(new BitmapDrawable(mContext.getResources(), thumbnail));
} else { } else {
td.setThumbnail(mDefaultThumbnailBackground); td.setThumbnail(mDefaultThumbnailBackground);
} }

View File

@@ -22,7 +22,10 @@ import android.content.Intent;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.content.res.Resources; import android.content.res.Resources;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.UserHandle; import android.os.UserHandle;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.util.Log; import android.util.Log;
@@ -68,7 +71,14 @@ public class Recents extends SystemUI implements RecentsComponent {
} }
} else { } 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(); final Resources res = mContext.getResources();
float thumbWidth = res float thumbWidth = res

View File

@@ -113,7 +113,7 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
/* package */ final static class ViewHolder { /* package */ final static class ViewHolder {
View thumbnailView; View thumbnailView;
ImageView thumbnailViewImage; ImageView thumbnailViewImage;
Bitmap thumbnailViewImageBitmap; Drawable thumbnailViewDrawable;
ImageView iconView; ImageView iconView;
TextView labelView; TextView labelView;
TextView descriptionView; TextView descriptionView;
@@ -151,7 +151,7 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
// the thumbnail later (if they both have the same dimensions) // the thumbnail later (if they both have the same dimensions)
updateThumbnail(holder, mRecentTasksLoader.getDefaultThumbnail(), false, false); updateThumbnail(holder, mRecentTasksLoader.getDefaultThumbnail(), false, false);
holder.iconView = (ImageView) convertView.findViewById(R.id.app_icon); 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.labelView = (TextView) convertView.findViewById(R.id.app_label);
holder.calloutLine = convertView.findViewById(R.id.recents_callout_line); holder.calloutLine = convertView.findViewById(R.id.recents_callout_line);
holder.descriptionView = (TextView) convertView.findViewById(R.id.app_description); 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) { public void recycleView(View v) {
ViewHolder holder = (ViewHolder) v.getTag(); ViewHolder holder = (ViewHolder) v.getTag();
updateThumbnail(holder, mRecentTasksLoader.getDefaultThumbnail(), false, false); updateThumbnail(holder, mRecentTasksLoader.getDefaultThumbnail(), false, false);
holder.iconView.setImageBitmap(mRecentTasksLoader.getDefaultIcon()); holder.iconView.setImageDrawable(mRecentTasksLoader.getDefaultIcon());
holder.iconView.setVisibility(INVISIBLE); holder.iconView.setVisibility(INVISIBLE);
holder.iconView.animate().cancel(); holder.iconView.animate().cancel();
holder.labelView.setText(null); 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) { if (thumbnail != null) {
// Should remove the default image in the frame // Should remove the default image in the frame
// that this now covers, to improve scrolling speed. // that this now covers, to improve scrolling speed.
// That can't be done until the anim is complete though. // 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 // 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 // we haven't set a bitmap before, or if the bitmap size has changed
if (h.thumbnailViewImageBitmap == null || if (h.thumbnailViewDrawable == null ||
h.thumbnailViewImageBitmap.getWidth() != thumbnail.getWidth() || h.thumbnailViewDrawable.getIntrinsicWidth() != thumbnail.getIntrinsicWidth() ||
h.thumbnailViewImageBitmap.getHeight() != thumbnail.getHeight()) { h.thumbnailViewDrawable.getIntrinsicHeight() != thumbnail.getIntrinsicHeight()) {
if (mFitThumbnailToXY) { if (mFitThumbnailToXY) {
h.thumbnailViewImage.setScaleType(ScaleType.FIT_XY); h.thumbnailViewImage.setScaleType(ScaleType.FIT_XY);
} else { } else {
Matrix scaleMatrix = new Matrix(); Matrix scaleMatrix = new Matrix();
float scale = mThumbnailWidth / (float) thumbnail.getWidth(); float scale = mThumbnailWidth / (float) thumbnail.getIntrinsicWidth();
scaleMatrix.setScale(scale, scale); scaleMatrix.setScale(scale, scale);
h.thumbnailViewImage.setScaleType(ScaleType.MATRIX); h.thumbnailViewImage.setScaleType(ScaleType.MATRIX);
h.thumbnailViewImage.setImageMatrix(scaleMatrix); h.thumbnailViewImage.setImageMatrix(scaleMatrix);
@@ -517,7 +517,7 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
} }
h.thumbnailView.setVisibility(View.VISIBLE); 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) { public void handleOnClick(View view) {
ViewHolder holder = (ViewHolder)view.getTag(); ViewHolder holder = (ViewHolder) view.getTag();
TaskDescription ad = holder.taskDescription; TaskDescription ad = holder.taskDescription;
final Context context = view.getContext(); final Context context = view.getContext();
final ActivityManager am = (ActivityManager) final ActivityManager am = (ActivityManager)
context.getSystemService(Context.ACTIVITY_SERVICE); context.getSystemService(Context.ACTIVITY_SERVICE);
Bitmap bm = holder.thumbnailViewImageBitmap;
boolean usingDrawingCache; Bitmap bm = null;
if (bm.getWidth() == holder.thumbnailViewImage.getWidth() && boolean usingDrawingCache = true;
bm.getHeight() == holder.thumbnailViewImage.getHeight()) { if (holder.thumbnailViewDrawable instanceof BitmapDrawable) {
usingDrawingCache = false; bm = ((BitmapDrawable) holder.thumbnailViewDrawable).getBitmap();
} else { if (bm.getWidth() == holder.thumbnailViewImage.getWidth() &&
bm.getHeight() == holder.thumbnailViewImage.getHeight()) {
usingDrawingCache = false;
}
}
if (usingDrawingCache) {
holder.thumbnailViewImage.setDrawingCacheEnabled(true); holder.thumbnailViewImage.setDrawingCacheEnabled(true);
bm = holder.thumbnailViewImage.getDrawingCache(); bm = holder.thumbnailViewImage.getDrawingCache();
usingDrawingCache = true;
} }
Bundle opts = (bm == null) ? Bundle opts = (bm == null) ?
null : null :

View File

@@ -29,7 +29,7 @@ public final class TaskDescription {
final String packageName; // used to override animations (see onClick()) final String packageName; // used to override animations (see onClick())
final CharSequence description; final CharSequence description;
private Bitmap mThumbnail; // generated by Activity.onCreateThumbnail() private Drawable mThumbnail; // generated by Activity.onCreateThumbnail()
private Drawable mIcon; // application package icon private Drawable mIcon; // application package icon
private CharSequence mLabel; // application package label private CharSequence mLabel; // application package label
private boolean mLoaded; private boolean mLoaded;
@@ -85,11 +85,11 @@ public final class TaskDescription {
mIcon = icon; mIcon = icon;
} }
public void setThumbnail(Bitmap thumbnail) { public void setThumbnail(Drawable thumbnail) {
mThumbnail = thumbnail; mThumbnail = thumbnail;
} }
public Bitmap getThumbnail() { public Drawable getThumbnail() {
return mThumbnail; return mThumbnail;
} }
} }