开发者

How to use cache memory for image download?

开发者 https://www.devze.com 2023-01-27 06:56 出处:网络
I am displayingimage from web using Image downloading logic,I want to image download at first time only,next time don\'tdownload image开发者_开发问答 from web,because First time downloaded image store

I am displaying image from web using Image downloading logic,I want to image download at first time only,next time don't download image开发者_开发问答 from web,because First time downloaded image store in cache memory so i display image from catch memory,In case,does not exits that image in cache memory,will download otherwise don't need download that image from web,How is possible?

Thanks Friends.


If you'd rather not reinvent the wheel here, you can either use droid-fu's image loading with caching built in, or dig deeper into its cachefu classes for more. Particularly, AbstractCache is a good base for a two-level cache; in this case, it keeps a smaller in-memory cache and if an SD card is available it'll keep extras there.


I am not an android dev but I believe there should be a way to write to the local memory. I.e write to a directory. I guess the image comes back from the web as an array of bytes which you can save to the local mem. Then you can probably just read it back whenever you need it again.


You can implement a "CacheManager" singleton class with a Hashtable cache, so when your download finish add to the cache object doing cache.put(imageUrl, imageView). Have to do this in a singleton to mantain the cache in the application lifecycle.


Here is a link to an image caching class.

http://theandroidcoder.com/utilities/android-image-download-and-caching/

It seems to work nicely and supports both memory and sdcard caching


Below the imageLoader class to maintain cache memory and Disk memory to image store in disk after download the images.

public class MyImageLoader {

private static final int DISK_CACHE_SIZE = 1024 * 1024 * 10; // 10MB
private static final String DISK_CACHE_SUBDIR = "ImageCache";
private DiskLruImageCache mDiskLruImageCache;
private ExecutorService executorService;
private LruCache<String, Bitmap> mMemoryCache;
private Map<ImageView, String> imageViews = Collections.synchronizedMap(new WeakHashMap<ImageView, String>());
private int byteCounts;
private int requiredHeight = 100, requiredWidth = 100; // setting default height & width as 100
private final int default_icon = R.drawable.no_image_friend;
CommonMethod mCommonMethod;

public MyImageLoader(Context context) {

    executorService = Executors.newFixedThreadPool(2);
    final int memClass = ((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE)).getMemoryClass();
    // Use 1/8th of the available memory for this memory cache.
    final int cacheSize = 1024 * 1024 * memClass / 8;

    mCommonMethod = new CommonMethod(context);
    mDiskLruImageCache = new DiskLruImageCache(context, DISK_CACHE_SUBDIR, DISK_CACHE_SIZE, CompressFormat.PNG, 70);

    mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {

        @Override
        protected int sizeOf(String key, Bitmap bitmap) {
            byteCounts = bitmap.getRowBytes() * bitmap.getHeight();
            return byteCounts;
        }
    };
}

public void ExecuteLoading(String urlString, ImageView mImageView) {

    imageViews.put(mImageView, urlString);
    Bitmap bitmap = getBitmapFromMemCache(urlString);

    if (bitmap != null){
        mImageView.setImageBitmap(bitmap);
    }
    else {
        executorService.submit(new LoadImages(urlString, mImageView));
        mImageView.setImageResource(default_icon);
    }
}

boolean ImageViewReused(String urlString, ImageView mImageView){
    String tag=imageViews.get(mImageView);
    if(tag==null || !tag.equals(urlString))
        return true;
    return false;
}

class LoadImages implements Runnable {
    String urlString;
    ImageView mImageView;
    DisplayImages images;

    public LoadImages(String urlString, ImageView mImageView) {
        this.urlString = urlString;
        this.mImageView = mImageView;
    }

    public void run() {

        if(!ImageViewReused(urlString, mImageView)){
            Bitmap bitmap = DownloadFromUrl(urlString);

            Bitmap mBitmapMask = mCommonMethod.makeMaskImageCrop(bitmap, R.drawable.image_thumb_mask, R.drawable.image_thumb);

            //TODO to mask image then bitmap pass
            addBitmapToDiskCache(urlString, mBitmapMask);

            DisplayImages images = new DisplayImages(urlString, mImageView, mBitmapMask);
            ((Activity) mImageView.getContext()).runOnUiThread(images);
        }
    }
}

class DisplayImages implements Runnable {
    Bitmap bitmap;
    String urlString;
    ImageView mImageView;

    public DisplayImages(String urlString, ImageView mImageView, Bitmap bitmap) {
        this.urlString = urlString;
        this.mImageView = mImageView;
        this.bitmap = bitmap;
    }

    public void run() {

        if(!ImageViewReused(urlString, mImageView)){
            if (bitmap != null)
                mImageView.setImageBitmap(bitmap);
            else
                mImageView.setImageResource(default_icon);
        }
    }
}

private Bitmap DownloadFromUrl(String urlString) {
    return decodeBitmapFromStream(urlString, getReqiredWidth(), getRequiredHeight());
}

private void addBitmapToMemoryCache(String key, Bitmap bitmap) {
    synchronized (mMemoryCache) {
        if (mMemoryCache.get(key) == null) {
            mMemoryCache.put(key, bitmap);
        }
    }
}
private Bitmap getBitmapFromMemCache(String key) {
    Bitmap bitmap = mMemoryCache.get(key);
    if(bitmap == null){
        bitmap = getBitmapFromDiskCache(key);
    }
    return bitmap;
}

private void addBitmapToDiskCache(String key, Bitmap bitmap) {
    synchronized (mDiskLruImageCache) {
        if (!mDiskLruImageCache.containsKey(String.valueOf(key.hashCode()))) {
            mDiskLruImageCache.put(String.valueOf(key.hashCode()), bitmap);
            addBitmapToMemoryCache(key, bitmap);
        }
    }
}

private Bitmap getBitmapFromDiskCache(String key) {
    return mDiskLruImageCache.getBitmap(String.valueOf(key.hashCode()));
}


private 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;

    inSampleSize = Math.min(width/reqWidth, height/reqHeight);

    return inSampleSize;
}

private static Bitmap decodeBitmapFromStream(String urlString, int reqWidth, int reqHeight) {

    URL url = null;
    InputStream is = null;
    try {
        url = new URL(urlString);
        is = (InputStream) url.getContent();
    } catch (Exception e) {
        e.printStackTrace();
    }

    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeStream(is, null, options);

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

    // As InputStream can be used only once we have to regenerate it again.
    try {
        is = (InputStream) url.getContent();
    } catch (IOException e) {
        e.printStackTrace();
    }
    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    return  BitmapFactory.decodeStream(is, null, options);
}

public int getRequiredHeight() {
    return requiredHeight;
}

public void setRequiredHeight(int longest, int requiredHeight) {
    this.requiredHeight = requiredHeight > longest ? longest : requiredHeight;
}

public int getReqiredWidth() {
    return requiredWidth;
}

public void setReqiredWidth(int longest, int requiredWidth) {
    this.requiredWidth = requiredWidth > longest ? longest : requiredWidth; 
}

public void clearCacheMemory() {
    if(mMemoryCache.size() > 0){
        mMemoryCache.evictAll();
    }
}

public void clearDiskMemory() {
    mDiskLruImageCache.clearCache();
}
}

hope you will get some idea and hint from the above code..

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号