t0s
t0s

Reputation: 1221

LruCache not working with imageAdapter

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

Answers (1)

Ifrit
Ifrit

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

Related Questions