LruCache不使用imageAdapter

时间:2014-05-27 01:16:53

标签: android bitmap android-lru-cache

我的资源中有11张图片。我使用GridView来显示它们。

因为图像在我的ImageAdapter类中占用了大量空间,所以我会根据教程here计算样本大小,然后对资源进行解码,以高效加载图像。

在我从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()尝试获取缓存的位图(如果它不为null) - 否则使用我上面提到的方法。

用于从缓存添加和获取位图我正在使用:

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

}

1 个答案:

答案 0 :(得分:1)

您不应该在getView()方法中实例化mMemoryCache。将它放在构造函数中。这就是为什么它永远无法在缓存中找到位图,因为你经常会破坏它并重新创建它。