原文链接: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
  1. publicclassImageFileCache
  2. {
  3. privatestaticfinalStringTAG="ImageFileCache";
  4. //图片缓存目录
  5. privatestaticfinalStringIMGCACHDIR="/sdcard/ImgCach";
  6. //保存的cache文件宽展名
  7. privatestaticfinalStringCACHETAIL=".cach";
  8. privatestaticfinalintMB=1024*1024;
  9. privatestaticfinalintCACHE_SIZE=1;
  10. //当SD卡剩余空间小于10M的时候会清理缓存
  11. privatestaticfinalintFREE_SD_SPACE_NEEDED_TO_CACHE=10;
  12. publicImageFileCache()
  13. {
  14. //清理部分文件缓存
  15. removeCache(IMGCACHDIR);
  16. }
  17. /**
  18. *从缓存中获取图片
  19. */
  20. publicBitmapgetImageFromFile(finalStringurl)
  21. {
  22. finalStringpath=IMGCACHDIR+"/"+convertUrlToFileName(url);
  23. Filefile=newFile(path);
  24. if(file!=null&&file.exists())
  25. {
  26. Bitmapbmp=BitmapFactory.decodeFile(path);
  27. if(bmp==null)
  28. {
  29. file.delete();
  30. }
  31. else
  32. {
  33. updateFileTime(path);
  34. Logger.d(TAG,"getbmpfromFileCache,url="+url);
  35. returnbmp;
  36. }
  37. }
  38. returnnull;
  39. }
  40. /**
  41. *将图片存入文件缓存
  42. */
  43. publicvoidsaveBitmapToFile(Bitmapbm,Stringurl)
  44. {
  45. if(bm==null){
  46. return;
  47. }
  48. //判断sdcard上的空间
  49. if(FREE_SD_SPACE_NEEDED_TO_CACHE>SdCardFreeSpace())
  50. {
  51. //SD空间不足
  52. return;
  53. }
  54. Stringfilename=convertUrlToFileName(url);
  55. FiledirFile=newFile(IMGCACHDIR);
  56. if(!dirFile.exists())
  57. dirFile.mkdirs();
  58. Filefile=newFile(IMGCACHDIR+"/"+filename);
  59. try
  60. {
  61. file.createNewFile();
  62. OutputStreamoutStream=newFileOutputStream(file);
  63. bm.compress(Bitmap.CompressFormat.JPEG,100,outStream);
  64. outStream.flush();
  65. outStream.close();
  66. }
  67. catch(FileNotFoundExceptione)
  68. {
  69. Logger.d(TAG,"FileNotFoundException");
  70. }
  71. catch(IOExceptione)
  72. {
  73. Logger.d(TAG,"IOException");
  74. }
  75. }
  76. /**
  77. *计算存储目录下的文件大小,
  78. *当文件总大小大于规定的CACHE_SIZE或者sdcard剩余空间小于FREE_SD_SPACE_NEEDED_TO_CACHE的规定
  79. *那么删除40%最近没有被使用的文件
  80. */
  81. privatebooleanremoveCache(StringdirPath)
  82. {
  83. Filedir=newFile(dirPath);
  84. File[]files=dir.listFiles();
  85. if(files==null)
  86. {
  87. returntrue;
  88. }
  89. if(!android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
  90. {
  91. returnfalse;
  92. }
  93. intdirSize=0;
  94. for(inti=0;i<files.length;i++)
  95. {
  96. if(files[i].getName().contains(CACHETAIL))
  97. {
  98. dirSize+=files[i].length();
  99. }
  100. }
  101. if(dirSize>CACHE_SIZE*MB||FREE_SD_SPACE_NEEDED_TO_CACHE>SdCardFreeSpace())
  102. {
  103. intremoveFactor=(int)(0.4*files.length);
  104. Arrays.sort(files,newFileLastModifSort());
  105. for(inti=0;i<removeFactor;i++)
  106. {
  107. if(files[i].getName().contains(CACHETAIL))
  108. {
  109. files[i].delete();
  110. }
  111. }
  112. }
  113. if(SdCardFreeSpace()<=CACHE_SIZE)
  114. {
  115. returnfalse;
  116. }
  117. returntrue;
  118. }
  119. /**
  120. *修改文件的最后修改时间
  121. */
  122. publicvoidupdateFileTime(Stringpath)
  123. {
  124. Filefile=newFile(path);
  125. longnewModifiedTime=System.currentTimeMillis();
  126. file.setLastModified(newModifiedTime);
  127. }
  128. /**
  129. *计算SD卡上的剩余空间
  130. */
  131. privateintSdCardFreeSpace()
  132. {
  133. StatFsstat=newStatFs(Environment.getExternalStorageDirectory().getPath());
  134. doublesdFreeMB=((double)stat.getAvailableBlocks()*(double)stat.getBlockSize())/MB;
  135. return(int)sdFreeMB;
  136. }
  137. /**
  138. *将url转成文件名
  139. */
  140. privateStringconvertUrlToFileName(Stringurl)
  141. {
  142. returnurl.hashCode()+CACHETAIL;
  143. }
  144. /**
  145. *根据文件的最后修改时间进行排序
  146. */
  147. privateclassFileLastModifSortimplementsComparator<File>
  148. {
  149. publicintcompare(Filefile0,Filefile1)
  150. {
  151. if(file0.lastModified()>file1.lastModified())
  152. {
  153. return1;
  154. }
  155. elseif(file0.lastModified()==file1.lastModified())
  156. {
  157. return0;
  158. }
  159. else
  160. {
  161. return-1;
  162. }
  163. }
  164. }
  165. }

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


更多相关文章

  1. YUV420P、YUV420SP、NV12、NV21和RGB互相转换并存储为JPEG以及PN
  2. Android 4.0 Launcher2源码分析——Laucher界面元素分解(主布局文
  3. 读懂Android (1):使用Android内部的DownloadProvider下载文件,并
  4. Android学习路线(二十八)保存文件

随机推荐

  1. Android推送通知指南
  2. Android使用Parcelable传递对象方法及注
  3. Android系统信息获取 之四:系统语言信息获
  4. 深入浅析Android手机卫士保存密码时进行m
  5. 【Android】android模拟器命令详解
  6. Android(安卓)-- ContentProvider的使用
  7. 查看Sqlite 数据库
  8. Android(安卓)学习手札(三) 视图(View)
  9. Android集成腾讯X5WebView
  10. android中的ellipsize