【构建Android缓存模块】(二)Memory Cache & File Cache

转自: http://blog.csdn.net/floodingfire/article/details/8249117


声明:Ryan的博客文章欢迎您的转载,但在转载的同时,请注明文章的来源出处,不胜感激! :-) 

http://my.oschina.net/ryanhoo/blog/93406

    节课我们讲到普通应用缓存Bitmap的实现分析,根据MVC的实现原理,我将这个简单的缓存实现单独写成一个模块,这样可以方便以后的使用,对于任意的需求,都属于一个可插拔式的功能。

    之前提到,这个缓存模块主要有两个子部件:

    Memory Cache:内存缓存的存取速度非常惊人,远远快于文件读取,如果没有内存限制,当然首选这种方式。遗憾的是我们有着16M的限制(当然大多数设备限制要高于Android官方说的这个数字),这也正是大Bitmap容易引起OOM的原因。Memory Cache将使用WeakHashMap作为缓存的中枢,当程序内存告急时,它会主动清理部分弱引用(因此,当引用指向为null,我们必须转向硬盘缓存读取数据,如果硬盘也没有,那还是重新下载吧)。

    能力越大,责任越大?人家只是跑得快了点儿,总得让人家休息,我们一定不希望让内存成为第一位跑完马拉松的Pheidippides,一次以后就挂了吧?作为精打细算的猿媛,我们只能将有限的内存分配给Memory Cache将更繁重的任务托付给任劳任怨的SDCard

    File Cache:硬盘读取速度当然不如内存,但是为了珍惜宝贵的流量,不让你的用户在月底没有流量时嚎叫着要删掉你开发的“流量杀手”,最好是避免重复下载。在第一次下载以后,将数据保存在本地即可。

    文件读写的技术并不是很新颖的技术,Java Core那点儿就够你用了。不过要记得我们可是将Bitmap写入文件啊,怎么写入呢?不用着急,Android的Bitmap本身就具备将数据写入OutputStream的能力。我将这些额外的方法写在一个帮助类中:BitmapHelper

01 public static boolean saveBitmap(File file, Bitmap bitmap){
02     if(file == null || bitmap == null)
03         return false;
04     try {
05         BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file));
06         return bitmap.compress(CompressFormat.JPEG, 100, out);
07     catch (FileNotFoundException e) {
08         e.printStackTrace();
09         return false;
10     }
11 }
    最后附上Memory Cache和File Cache的具体代码,非常简单。


01 public class MemoryCache {
02     private static final String TAG = "MemoryCache";
03      
04     //WeakReference Map: key=string, value=Bitmap
05     private WeakHashMap<String, Bitmap> cache = new WeakHashMap<String, Bitmap>();
06      
07     /**
08      * Search the memory cache by a unique key.
09      * @param key Should be unique.
10      * @return The Bitmap object in memory cache corresponding to specific key.
11      * */
12     public Bitmap get(String key){
13         if(key != null)
14             return cache.get(key);
15         return null;
16     }
17      
18     /**
19      * Put a bitmap into cache with a unique key.
20      * @param key Should be unique.
21      * @param value A bitmap.
22      * */
23     public void put(String key, Bitmap value){
24         if(key != null && !"".equals(key) && value != null){
25             cache.put(key, value);
26             //Log.i(TAG, "cache bitmap: " + key);
27             Log.d(TAG, "size of memory cache: " + cache.size());
28         }
29     }
30  
31     /**
32      * clear the memory cache.
33      * */
34     public void clear() {
35         cache.clear();
36     }
37 }
01 public class FileCache {
02      
03     private static final String TAG = "MemoryCache";
04      
05     private File cacheDir;  //the directory to save images
06  
07     /**
08      * Constructor
09      * @param context The context related to this cache.
10      * */
11     public FileCache(Context context) {
12         // Find the directory to save cached images
13         if (android.os.Environment.getExternalStorageState()
14                 .equals(android.os.Environment.MEDIA_MOUNTED))
15             cacheDir = new File(
16                     android.os.Environment.getExternalStorageDirectory(),
17                     Config.CACHE_DIR);
18         else
19             cacheDir = context.getCacheDir();
20         if (!cacheDir.exists())
21             cacheDir.mkdirs();
22          
23         Log.d(TAG, "cache dir: " + cacheDir.getAbsolutePath());
24     }
25  
26     /**
27      * Search the specific image file with a unique key.
28      * @param key Should be unique.
29      * @return Returns the image file corresponding to the key.
30      * */
31     public File getFile(String key) {
32         File f = new File(cacheDir, key);
33         if (f.exists()){
34             Log.i(TAG, "the file you wanted exists " + f.getAbsolutePath());
35             return f;
36         }else{
37             Log.w(TAG, "the file you wanted does not exists: " + f.getAbsolutePath());
38         }
39  
40         return null;
41     }
42  
43     /**
44      * Put a bitmap into cache with a unique key.
45      * @param key Should be unique.
46      * @param value A bitmap.
47      * */
48     public void put(String key, Bitmap value){
49         File f = new File(cacheDir, key);
50         if(!f.exists())
51             try {
52                 f.createNewFile();
53             catch (IOException e) {
54                 e.printStackTrace();
55             }
56         //Use the util's function to save the bitmap.
57         if(BitmapHelper.saveBitmap(f, value))
58             Log.d(TAG, "Save file to sdcard successfully!");
59         else
60             Log.w(TAG, "Save file to sdcard failed!");
61          
62     }
63      
64     /**
65      * Clear the cache directory on sdcard.
66      * */
67     public void clear() {
68         File[] files = cacheDir.listFiles();
69         for (File f : files)
70             f.delete();
71     }
72 }
    没什么难的地方,直接贴代码。下节课我讲讲解如何使用异步任务下载数据,以及使用Controller操作Model,控制View的显示。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值