Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to store images in Cache Memory

I am totally blank on this. I want to download the images from a Url and have to store it internally so that next time I need not connect to web and instead retrieve it from cache memory. But I am not sure how to do this. Can anyone help me with a code snippet.

like image 802
Andro Selva Avatar asked Jul 05 '11 09:07

Andro Selva


People also ask

Does cache store images?

Cached data are files, scripts, images, and other multimedia stored on your device after opening an app or visiting a website for the first time. This data is then used to quickly gather information about the app or website every time revisited, reducing load time.

Can images be cached?

Let's review: To cache an image is to store it in the local storage of the device so that it can be accessed quickly next time around without any network requests.

Should images be cached?

Generally yes, images should be cached in at least memory, and depending on your app (how likely is it to be reused,etc) in memory and storage. If you want to support your 3rd point (displaying when offline), you need to do storage caching, and memory caching is optional but probably a good idea.

Can cache memory store data permanently?

Disk cache memory: Instead of the CPU having to wait for data to be stored on a slow hard disk, it sends the information to be saved to the disk cache memory. From the disk cache, the data is written to the hard drive, which stores it permanently.


2 Answers

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.StreamCorruptedException;
import java.text.SimpleDateFormat;
import java.util.HashMap;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Environment;
import android.util.Log;

public class CacheStore {
    private static CacheStore INSTANCE = null;
    private HashMap<String, String> cacheMap;
    private HashMap<String, Bitmap> bitmapMap;
    private static final String cacheDir = "/Android/data/com.yourbusiness/cache/";
    private static final String CACHE_FILENAME = ".cache";

    @SuppressWarnings("unchecked")
    private CacheStore() {
        cacheMap = new HashMap<String, String>();
        bitmapMap = new HashMap<String, Bitmap>();
        File fullCacheDir = new File(Environment.getExternalStorageDirectory().toString(),cacheDir);
        if(!fullCacheDir.exists()) {
            Log.i("CACHE", "Directory doesn't exist");
            cleanCacheStart();
            return;
        }
        try {
            ObjectInputStream is = new ObjectInputStream(new BufferedInputStream(new FileInputStream(new File(fullCacheDir.toString(), CACHE_FILENAME))));
            cacheMap = (HashMap<String,String>)is.readObject();
            is.close();
        } catch (StreamCorruptedException e) {
            Log.i("CACHE", "Corrupted stream");
            cleanCacheStart();
        } catch (FileNotFoundException e) {
            Log.i("CACHE", "File not found");
            cleanCacheStart();
        } catch (IOException e) {
            Log.i("CACHE", "Input/Output error");
            cleanCacheStart();
        } catch (ClassNotFoundException e) {
            Log.i("CACHE", "Class not found");
            cleanCacheStart();
        }
    }

    private void cleanCacheStart() {
        cacheMap = new HashMap<String, String>();
        File fullCacheDir = new File(Environment.getExternalStorageDirectory().toString(),cacheDir);
        fullCacheDir.mkdirs();
        File noMedia = new File(fullCacheDir.toString(), ".nomedia");
        try {
            noMedia.createNewFile();
            Log.i("CACHE", "Cache created");
        } catch (IOException e) {
            Log.i("CACHE", "Couldn't create .nomedia file");
            e.printStackTrace();
        }
    }

    private synchronized static void createInstance() {
        if(INSTANCE == null) {
            INSTANCE = new CacheStore();
        }
    }

    public static CacheStore getInstance() {
        if(INSTANCE == null) createInstance();
        return INSTANCE;
    }

    public void saveCacheFile(String cacheUri, Bitmap image) {
        File fullCacheDir = new File(Environment.getExternalStorageDirectory().toString(),cacheDir);
        String fileLocalName = new SimpleDateFormat("ddMMyyhhmmssSSS").format(new java.util.Date())+".PNG";
        File fileUri = new File(fullCacheDir.toString(), fileLocalName);
        FileOutputStream outStream = null;
        try {
            outStream = new FileOutputStream(fileUri);
            image.compress(Bitmap.CompressFormat.PNG, 100, outStream);
            outStream.flush();
            outStream.close();
            cacheMap.put(cacheUri, fileLocalName);
            Log.i("CACHE", "Saved file "+cacheUri+" (which is now "+fileUri.toString()+") correctly");
            bitmapMap.put(cacheUri, image);
            ObjectOutputStream os = new ObjectOutputStream(new BufferedOutputStream(
                    new FileOutputStream(new File(fullCacheDir.toString(), CACHE_FILENAME))));
            os.writeObject(cacheMap);
            os.close();
        } catch (FileNotFoundException e) {
            Log.i("CACHE", "Error: File "+cacheUri+" was not found!");
            e.printStackTrace();
        } catch (IOException e) {
            Log.i("CACHE", "Error: File could not be stuffed!");
            e.printStackTrace();
        }
    }

    public Bitmap getCacheFile(String cacheUri) {
        if(bitmapMap.containsKey(cacheUri)) return (Bitmap)bitmapMap.get(cacheUri);

        if(!cacheMap.containsKey(cacheUri)) return null;
        String fileLocalName = cacheMap.get(cacheUri).toString();
        File fullCacheDir = new File(Environment.getExternalStorageDirectory().toString(),cacheDir);
        File fileUri = new File(fullCacheDir.toString(), fileLocalName);
        if(!fileUri.exists()) return null;

        Log.i("CACHE", "File "+cacheUri+" has been found in the Cache");
        Bitmap bm = BitmapFactory.decodeFile(fileUri.toString());
        bitmapMap.put(cacheUri, bm);
        return bm;
    }
}
like image 120
Rupok Avatar answered Nov 15 '22 08:11

Rupok


Although the selected answer is correct, but it's a bit lengthy as its downloading image from the server first. Those who are just looking at how to save bitmap into cache for them we can use Android's native LruCache library. Here I have written a detailed article on the topic LruCache in Java & LruCache in Kotlin.

Java Class to save Bitmap in Cache:

import android.graphics.Bitmap;
import androidx.collection.LruCache;

public class MyCache {

    private static MyCache instance;
    private LruCache<Object, Object> lru;

    private MyCache() {

        lru = new LruCache<Object, Object>(1024);

    }

    public static MyCache getInstance() {

        if (instance == null) {
            instance = new MyCache();
        }
        return instance;

    }

    public LruCache<Object, Object> getLru() {
        return lru;
    }

    public void saveBitmapToCahche(String key, Bitmap bitmap){

        try {
            MyCache.getInstance().getLru().put(key, bitmap);
        }catch (Exception e){}
    }

    public Bitmap retrieveBitmapFromCache(String key){

        try {
            Bitmap bitmap = (Bitmap) MyCache.getInstance().getLru().get(key);
            return bitmap;
        }catch (Exception e){}
        return null;
    }

}
like image 39
Asad Ali Choudhry Avatar answered Nov 15 '22 07:11

Asad Ali Choudhry