android中图片的三级cache策略(内存、文件、网络)之三:文件缓存策略
16lz
2021-01-23
原文链接:http://blog.csdn.net/singwhatiwanna/article/details/17588159
前言
如果想很好地理解下面的故事,请参看我半年前写的两篇博文:android中图片的三级cache策略(内存、文件、网络) 一和android中左右滑屏的实现(广告位banner组件),还有昨天晚上写的android中图片的三级cache策略(内存、文件、网络)之二:内存缓存策略。
文件缓存策略
当一张图片从网络下载成功以后,这个图片会被加入内存缓存和文件缓存,对于文件缓存来说,这张图片将被以url的哈希值加cach后缀名的形式存储在SD卡上,这样,当下一次再需要同一个url的图片的时候,就不需要从网络下载了,而是直接通过url来进行查找。同时一张图片被访问时,它的最后修改时间将被更新,这样的意义在于:当SD卡空间不足的时候,将会按照最后修改时间来删除40%缓存的图片,确切来说,那些修改时间比较早的图片将会被删除。代码展示
[java] view plain copy
- publicclassImageFileCache
- {
- privatestaticfinalStringTAG="ImageFileCache";
- //图片缓存目录
- privatestaticfinalStringIMGCACHDIR="/sdcard/ImgCach";
- //保存的cache文件宽展名
- privatestaticfinalStringCACHETAIL=".cach";
- privatestaticfinalintMB=1024*1024;
- privatestaticfinalintCACHE_SIZE=1;
- //当SD卡剩余空间小于10M的时候会清理缓存
- privatestaticfinalintFREE_SD_SPACE_NEEDED_TO_CACHE=10;
- publicImageFileCache()
- {
- //清理部分文件缓存
- removeCache(IMGCACHDIR);
- }
- /**
- *从缓存中获取图片
- */
- publicBitmapgetImageFromFile(finalStringurl)
- {
- finalStringpath=IMGCACHDIR+"/"+convertUrlToFileName(url);
- Filefile=newFile(path);
- if(file!=null&&file.exists())
- {
- Bitmapbmp=BitmapFactory.decodeFile(path);
- if(bmp==null)
- {
- file.delete();
- }
- else
- {
- updateFileTime(path);
- Logger.d(TAG,"getbmpfromFileCache,url="+url);
- returnbmp;
- }
- }
- returnnull;
- }
- /**
- *将图片存入文件缓存
- */
- publicvoidsaveBitmapToFile(Bitmapbm,Stringurl)
- {
- if(bm==null){
- return;
- }
- //判断sdcard上的空间
- if(FREE_SD_SPACE_NEEDED_TO_CACHE>SdCardFreeSpace())
- {
- //SD空间不足
- return;
- }
- Stringfilename=convertUrlToFileName(url);
- FiledirFile=newFile(IMGCACHDIR);
- if(!dirFile.exists())
- dirFile.mkdirs();
- Filefile=newFile(IMGCACHDIR+"/"+filename);
- try
- {
- file.createNewFile();
- OutputStreamoutStream=newFileOutputStream(file);
- bm.compress(Bitmap.CompressFormat.JPEG,100,outStream);
- outStream.flush();
- outStream.close();
- }
- catch(FileNotFoundExceptione)
- {
- Logger.d(TAG,"FileNotFoundException");
- }
- catch(IOExceptione)
- {
- Logger.d(TAG,"IOException");
- }
- }
- /**
- *计算存储目录下的文件大小,
- *当文件总大小大于规定的CACHE_SIZE或者sdcard剩余空间小于FREE_SD_SPACE_NEEDED_TO_CACHE的规定
- *那么删除40%最近没有被使用的文件
- */
- privatebooleanremoveCache(StringdirPath)
- {
- Filedir=newFile(dirPath);
- File[]files=dir.listFiles();
- if(files==null)
- {
- returntrue;
- }
- if(!android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
- {
- returnfalse;
- }
- intdirSize=0;
- for(inti=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())
- {
- intremoveFactor=(int)(0.4*files.length);
- Arrays.sort(files,newFileLastModifSort());
- for(inti=0;i<removeFactor;i++)
- {
- if(files[i].getName().contains(CACHETAIL))
- {
- files[i].delete();
- }
- }
- }
- if(SdCardFreeSpace()<=CACHE_SIZE)
- {
- returnfalse;
- }
- returntrue;
- }
- /**
- *修改文件的最后修改时间
- */
- publicvoidupdateFileTime(Stringpath)
- {
- Filefile=newFile(path);
- longnewModifiedTime=System.currentTimeMillis();
- file.setLastModified(newModifiedTime);
- }
- /**
- *计算SD卡上的剩余空间
- */
- privateintSdCardFreeSpace()
- {
- StatFsstat=newStatFs(Environment.getExternalStorageDirectory().getPath());
- doublesdFreeMB=((double)stat.getAvailableBlocks()*(double)stat.getBlockSize())/MB;
- return(int)sdFreeMB;
- }
- /**
- *将url转成文件名
- */
- privateStringconvertUrlToFileName(Stringurl)
- {
- returnurl.hashCode()+CACHETAIL;
- }
- /**
- *根据文件的最后修改时间进行排序
- */
- privateclassFileLastModifSortimplementsComparator<File>
- {
- publicintcompare(Filefile0,Filefile1)
- {
- if(file0.lastModified()>file1.lastModified())
- {
- return1;
- }
- elseif(file0.lastModified()==file1.lastModified())
- {
- return0;
- }
- else
- {
- return-1;
- }
- }
- }
- }
说明:上述代码很好理解而且都有注释,不用多说了。
更多相关文章
- YUV420P、YUV420SP、NV12、NV21和RGB互相转换并存储为JPEG以及PN
- Android 4.0 Launcher2源码分析——Laucher界面元素分解(主布局文
- 读懂Android (1):使用Android内部的DownloadProvider下载文件,并
- Android学习路线(二十八)保存文件