Reputation: 1221
I'm having 11 images in my resources. I use a GridView to display them.
Because images take a lot of space in my ImageAdapter class I calculate sample size and then decode the resouce as per the tutorial here to efficient load an image.
Before I return the decoded bitmap from decodeSampledBitmapFromResource
I'm adding the bitmap to 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
which leads to my getView()
to try and get cached bitmap if it's not null - else use the method I mentioned above.
For adding and getting bitmaps from cache I'm using :
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);
}
What happens is that if ( cachedBitmap != null )
is never true which makes me believe something is wrong.
full code for the class :
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);
}
}
Upvotes: 0
Views: 393
Reputation: 6821
You should not be instantiating the mMemoryCache in the getView() method. Place that in the constructor. That's why it can never find the bitmap in cache, because you are constantly destroying and recreating it.
Upvotes: 1