android中图片的三级cache策略(内存 文件 网络)之三 文件缓存策略

               

前言

如果想很好地理解下面的故事,请参看我半年前写的两篇博文: android中图片的三级cache策略(内存、文件、网络) 一 和  android中左右滑屏的实现(广告位banner组件),还有昨天晚上写的 android中图片的三级cache策略(内存、文件、网络)之二:内存缓存策略

文件缓存策略

当一张图片从网络下载成功以后,这个图片会被加入内存缓存和文件缓存,对于文件缓存来说,这张图片将被以url的哈希值加cach后缀名的形式存储在SD卡上,这样,当下一次再需要同一个url的图片的时候,就不需要从网络下载了,而是直接通过url来进行查找。同时一张图片被访问时,它的最后修改时间将被更新,这样的意义在于:当SD卡空间不足的时候,将会按照最后修改时间来删除40%缓存的图片,确切来说,那些修改时间比较早的图片将会被删除。

代码展示

public class ImageFileCache{    private static final String TAG = "ImageFileCache";     //图片缓存目录    private static final String IMGCACHDIR = "/sdcard/ImgCach";        //保存的cache文件宽展名    private static final String CACHETAIL = ".cach";                                                                private static final int MB = 1024*1024;        private static final int CACHE_SIZE = 1;        //当SD卡剩余空间小于10M的时候会清理缓存    private static final int FREE_SD_SPACE_NEEDED_TO_CACHE = 10;                                                                    public ImageFileCache()     {        //清理部分文件缓存        removeCache(IMGCACHDIR);          }                                                                    /**      * 从缓存中获取图片      */    public Bitmap getImageFromFile(final String url)     {            final String path = IMGCACHDIR + "/" + convertUrlToFileName(url);        File file = new File(path);        if (file != null && file.exists())         {            Bitmap bmp = BitmapFactory.decodeFile(path);            if (bmp == null)             {                file.delete();            }             else             {                updateFileTime(path);                Logger.d(TAG, "get bmp from FileCache,url=" + url);                return bmp;            }        }        return null;    }                                                                    /**     * 将图片存入文件缓存      */    public void saveBitmapToFile(Bitmap bm, String url)     {        if (bm == null) {            return;        }        //判断sdcard上的空间        if (FREE_SD_SPACE_NEEDED_TO_CACHE > SdCardFreeSpace())         {            //SD空间不足            return;        }                String filename = convertUrlToFileName(url);        File dirFile = new File(IMGCACHDIR);        if (!dirFile.exists())            dirFile.mkdirs();        File file = new File(IMGCACHDIR +"/" + filename);        try         {            file.createNewFile();            OutputStream outStream = new FileOutputStream(file);            bm.compress(Bitmap.CompressFormat.JPEG, 100, outStream);            outStream.flush();            outStream.close();        }         catch (FileNotFoundException e)         {            Logger.d(TAG, "FileNotFoundException");        }         catch (IOException e)         {            Logger.d(TAG, "IOException");        }    }                                                                     /**     * 计算存储目录下的文件大小,     * 当文件总大小大于规定的CACHE_SIZE或者sdcard剩余空间小于FREE_SD_SPACE_NEEDED_TO_CACHE的规定     * 那么删除40%最近没有被使用的文件     */    private boolean removeCache(String dirPath)     {        File dir = new File(dirPath);        File[] files = dir.listFiles();                if (files == null)         {            return true;        }                if (!android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))        {            return false;        }                                                                    int dirSize = 0;        for (int i = 0; i < files.length; i++)         {            if (files[i].getName().contains(CACHETAIL))             {                dirSize += files[i].length();            }        }                                                                    if (dirSize > CACHE_SIZE * MB || FREE_SD_SPACE_NEEDED_TO_CACHE > SdCardFreeSpace())         {            int removeFactor = (int) (0.4 * files.length);            Arrays.sort(files, new FileLastModifSort());            for (int i = 0; i < removeFactor; i++)             {                if (files[i].getName().contains(CACHETAIL))                 {                    files[i].delete();                }            }        }                                                                    if (SdCardFreeSpace() <= CACHE_SIZE)         {            return false;        }                                                                            return true;    }                                                                    /**     * 修改文件的最后修改时间     */    public void updateFileTime(String path)     {        File file = new File(path);        long newModifiedTime = System.currentTimeMillis();        file.setLastModified(newModifiedTime);    }                                                                    /**      * 计算SD卡上的剩余空间      */    private int SdCardFreeSpace()    {        StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath());        double sdFreeMB = ((double)stat.getAvailableBlocks() * (double) stat.getBlockSize()) / MB;        return (int) sdFreeMB;    }                                                                     /**      * 将url转成文件名      */    private String convertUrlToFileName(String url)    {     return url.hashCode() + CACHETAIL;    }                                                                    /**     * 根据文件的最后修改时间进行排序     */    private class FileLastModifSort implements Comparator<File>     {        public int compare(File file0, File file1)         {            if (file0.lastModified() > file1.lastModified())            {                return 1;            }             else if (file0.lastModified() == file1.lastModified())             {                return 0;            }             else             {                return -1;            }        }    }}

说明:上述代码很好理解而且都有注释,不用多说了。

到这里,整个banner体系的代码都被介绍了,希望代码中的思想能够对大家有所启发,谢谢大家的捧场!

           

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow

猜你喜欢

转载自blog.csdn.net/qq_43661383/article/details/87376778