如何将图像存储在缓存内存中

6

我完全不知道该怎么做。我想从Url下载图片,并将其存储在内部,以便下次无需连接到网络,而是从缓存中检索。但我不确定如何做到这一点。有人能帮我提供一段代码片段吗?


你试过著名的Fedor代码吗? - ingsaurabh
抱歉!你指的是什么? - Andro Selva
1
我在谈论这个问题:https://dev59.com/Y3RB5IYBdhLWcg3wtZMV - ingsaurabh
@Android_Selva,Saurabh关于使用此示例是正确的。 - Paresh Mayani
2个回答

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

将数据存储到SD卡中:https://dev59.com/4FXTa4cB1Zd3GeqP5did - Rupok
链接已经失效,无法提供翻译。 - John Sardinha

2
尽管所选答案是正确的,但它有点冗长,因为它首先从服务器下载图像。对于那些只想知道如何将位图保存到缓存中的人,我们可以使用Android的本地LruCache库。在这里,我写了一篇关于主题的详细文章:Java中的LruCacheKotlin中的LruCache

用于将位图保存在缓存中的Java类:

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

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接