我的资源中有 11 张图片。我使用 GridView 来显示它们。
因为图像在我的 ImageAdapter 类中占用大量空间,所以我计算样本大小,然后按照此处的教程解码资源以有效加载图像。
在我返回解码的位图之前,我将decodeSampledBitmapFromResource
位图添加到 LruCache :
Bitmap b = BitmapFactory.decodeResource(res, resId, options);
String key = Integer.toString(resId);
// Log.i("byte", "b.getByteCount()==" + b.getByteCount());
addBitmapToMemoryCache(key, b); //add to cache
如果它不为空,这导致我getView()
尝试获取缓存的位图 - 否则使用我上面提到的方法。
为了从缓存中添加和获取位图,我正在使用:
public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
if (getBitmapFromMemCache(key) == null) {
Log.i("addbitmaptocache", "Add key= " + key);
mMemoryCache.put(key, bitmap);
}
}
public Bitmap getBitmapFromMemCache(String key) {
Log.i("getbitmaptocache", "GET KEY= " + key);
return mMemoryCache.get(key);
}
发生的事情if ( cachedBitmap != null )
从来都不是真的,这让我相信有些事情是错误的。
类的完整代码:
public class ImageAdapter extends BaseAdapter {
private Context mContext;
private int wid;
private static final String AdapterTAG="adapterTAG";
// private ImageView imageView;
private Bitmap mBitmap;
private LruCache<String, Bitmap> mMemoryCache;
public ImageAdapter(Context c, int wid) {
mContext = c;
this.wid = wid;
}
public int getCount() {
return mThumbIds.length;
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
// create a new ImageView for each item referenced by the Adapter
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolderItem viewHolder;
int new_width = wid/2;
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.grid_item, parent, false);
// well set up the ViewHolder
viewHolder = new ViewHolderItem();
viewHolder.textViewItem = (TextView) convertView.findViewById(R.id.textId);
viewHolder.imageViewItem = (ImageView) convertView.findViewById(R.id.imageId);
// store the holder with the view.
convertView.setTag(viewHolder);
} else{
viewHolder = (ViewHolderItem) convertView.getTag();
}
/** ******************** Caching ******************** **/
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
// Log.i("max", "maxMemory== " + maxMemory );
// Use 1/8th of the available memory for this memory cache.
final int cacheSize = maxMemory / 4;
// Log.i("cachesize", "cachesize== " + cacheSize);
mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
@Override
protected int sizeOf(String key, Bitmap bitmap) {
return bitmap.getByteCount() / 1024;
}
};
//Log.i("mMemoryCache", "mMemoryCache= " + mMemoryCache);
viewHolder.textViewItem.setId(position);
viewHolder.imageViewItem.getLayoutParams().width = new_width -5;
viewHolder.imageViewItem.getLayoutParams().height = new_width -5;
viewHolder.imageViewItem.setScaleType(ImageView.ScaleType.CENTER_CROP);
viewHolder.imageViewItem.setPadding(0, 0, 0, 0);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = false;
final String imageKey = String.valueOf(mThumbIds[position]);
final Bitmap cachedBitmap = getBitmapFromMemCache(imageKey); // use cached Bitmap or ... decode
if ( cachedBitmap != null ) {
Log.i("cached", "CACHED BITMAP FOR THE WIN!!!!");
viewHolder.imageViewItem.setImageBitmap(cachedBitmap);
} else {
viewHolder.imageViewItem.setImageBitmap(decodeSampledBitmapFromResource(mContext.getResources(), mThumbIds[position] , new_width, 200));
}
return convertView;
}
static class ViewHolderItem {
TextView textViewItem;
ImageView imageViewItem;
}
// references to our images
private Integer[] mThumbIds = {
R.drawable.wallpaper0, R.drawable.wallpaper1,
R.drawable.wallpaper2, R.drawable.wallpaper3,
R.drawable.wallpaper4, R.drawable.wallpaper5,
R.drawable.wallpaper6, R.drawable.wallpaper7,
R.drawable.wallpaper8, R.drawable.wallpaper9,
R.drawable.wallpaper10
};
public Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {
// Log.i("req", "reqWidth= " + reqWidth + " reqHeight=" + reqHeight ); // params
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
String imageType = options.outMimeType;
Log.i("options", "Width== " + imageWidth + " Height== " + imageHeight + " Type== " + imageType );
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
options.inPurgeable = true;
options.inInputShareable = true;
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
Bitmap b = BitmapFactory.decodeResource(res, resId, options);
String key = Integer.toString(resId);
// Log.i("byte", "b.getByteCount()==" + b.getByteCount());
addBitmapToMemoryCache(key, b); //add to cache
return b;
}
public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
Log.i("sample", "size=" +inSampleSize );
return inSampleSize;
}
public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
if (getBitmapFromMemCache(key) == null) {
Log.i("addbitmaptocache", "Add key= " + key);
mMemoryCache.put(key, bitmap);
}
}
public Bitmap getBitmapFromMemCache(String key) {
Log.i("getbitmaptocache", "GET KEY= " + key);
return mMemoryCache.get(key);
}
}