`
从此醉
  • 浏览: 1040017 次
  • 性别: Icon_minigender_1
  • 来自: US
社区版块
存档分类
最新评论

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体系的代码都被介绍了,希望代码中的思想能够对大家有所启发,谢谢大家的捧场!

分享到:
评论

相关推荐

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

    1.简介 现在android应用中不可避免的要使用图片,有些图片是可以变化的,需要每次启动时从网络拉取,这种场景在有广告位的应用以及纯...这里我采用 内存-文件-网络 三层cache机制,其中内存缓存包括强引用缓存和软引

    Android自定义图片三级缓存

    图片的三级缓存策略,即内存、硬盘和网络(其实网络不算是缓存,姑且算是吧~~),内存缓存使用的时LRUCache,这是一个存放键值对的列表,如果内存不够会根据最近使用次数的多少来删除其中的一个item,最少使用的就会...

    Android网络图片缓存(网络cache和本地)

    Android网络图片缓存 ,分为网络缓存和本地缓存,节省了每次下载图片的流量,也提高了加载速度。

    CacheManage::fire:android缓存管理器,分为内存缓存和文件缓存两种 先取内存数据,没有再从文件缓存中取

    android缓存管理器,分为两级缓存:内存缓存和文件缓存;先取内存数据,没有再从文件缓存中获取特点封装,继承其所有功能二级缓存内存缓存(采用SoftReference和LruCache,防止内存溢出)文件缓存(由ASimpleCache...

    J2Cache 基于内存和 Redis 的两级 Java 缓存框架

    第一级缓存使用内存(同时支持 Ehcache 2.x、Ehcache 3.x 和 Caffeine),第二级缓存使用 Redis(推荐)/Memcached 。 由于大量的缓存读取会导致 L2 的网络成为整个系统的瓶颈,因此 L1 的目标是降低对 L2 的读取次数。 ...

    高速缓存(Cache)的Verilog代码

    该工程包含数据缓存D_Cache和指令缓存I_Cache的Verilog代码和仿真文件,Cache的详细技术参数包含在.v文件的注释中。 直接相连16KB D_Cache Cache写策略: 写回法+写分配 (二路)组相连16KB I_Cache Cache替换策略: ...

    Volley+Cache 实现网络缓存以及内存缓存

    Volley+Cache 实现网络缓存以及内存缓存

    加载大图片、内存缓存、diskCache

    谷歌文档翻译,如何加载大图,如何加载网络图片,LruCache缓存图片,处理网络图片并发加载,ListView加载网络图片错位,本地缓存图片diskcache,Activity横竖屏时缓存不清除

    三级缓存DiskLruCache+LruCache

    内存-文件-网络 三层cache机制,其中内存缓存包括强引用缓存和软引用缓存(SoftReference),其实网络不算cache,这里姑且也把它划到缓存的层次结构中。当根据url向网络拉取图片的时候,先从内存中找,如果内存中...

    android 图片缓存第三方类库

    用于android 图片的缓存,策略:cache中检索,有则display,无则下载之,存入cache,display,真的拿不到图片则显示设定的默认图(主题建议为找不到图片),功能尚在完善中,暂不开放源代码。我的博客:...

    android 缓存 ACache

    很详细的备注 不想了解的可以下载放倒项目里直接用 有问题联系我就好 我会尽快给答复

    linux 查看 cache 中文件

    安装此工具后,可以查看系统内存中 cache 包含的文件。 在编译安装此工具之前需要安装GCC包

    Android图片缓存

    Android开发中实现图片缓存机制,可以直接导入eclipse后到处jar使用。

    图片缓存DiskCache demo

    图片缓存DiskCache demo,blog地址:http://blog.csdn.net/hfut11/article/details/48296823

    android图片缓存优化,内存缓存加sdcard缓存,性能很好,防止oom

    一个图片内存缓存和sdcard缓存的例子,经过很好的优化,性能很好,能有效的防止oom.

    Android WebView 缓存详解

    而缓存的索引放在:/data/data//databases 对应的文件放在:/data/data/package_name/cache/webviewCacheChromunm下 数据缓存:分为AppCache和DOM Storage两种 我们开发者可以自行控制的就是这些缓存资源 AppCache...

    ARM高速缓存(Cache)Verilog代码 包含ISE工程

    该工程包含数据缓存D_Cache和指令缓存I_Cache的Verilog代码和仿真文件,附带可运行的ISE工程文件,Cache的详细技术参数包含在.v文件的注释中。 直接相连16KB D_Cache Cache写策略: 写回法+写分配 (二路)组相连16KB ...

    hcache缓存cache查看工具

    #直接下载hcache文件到linux,并使用该文件即可 ...#ps: 一般进程缓存的文件并不会太大, 最大的可能性是读写了大文件导致文件被缓存,建议检查下是否存在无用的超大日志,查找大于1G的文件 find / -type f

    Android WebView cache 缓存 在线 视频播放

    WebView cache 缓存 在线 视频播放 离线阅读

Global site tag (gtag.js) - Google Analytics