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.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);
}

View File

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

View File

@@ -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 :

View File

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