您的位置:首页 > 移动开发 > Android开发

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

2012-12-02 19:24 344 查看
转载声明: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
}
view
source

print?

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的显示。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息