cache-1
来源:互联网 发布:白苹果怎么备份数据 编辑:程序博客网 时间:2024/05/22 11:49
【转】http://www.jxmfkj.com/archives/189
假设你开发了一个聊天程序,它的好友列表中显示从网络获取的好友头像。可是如果用户发现每次进入好友列表的时候,程序都要重新下载头像才能进行显示,甚至当把列表滑动到底部再重新滑动回顶部的时候,刚才已经加载完成了的头像竟然又变成了空白图片开始重新加载,这将是一种糟糕的用户体验。为了解决这种问题,你需要使用高速缓存技术——Cache。
什么是Cache?
Cache,高速缓存,原意是指计算机中一块比内存更高速容量更小的存储器。更广义地说,Cache指对于最近使用过的信息的可高速读取的存储块。而本文要讲的Cache技术,指的就是将最近使用过的Bitmap缓存在手机的内存与磁盘中,来实现再次使用Bitmap时的瞬时加载,以节省用户的时间和手机流量。
下面将针对Android中的两种Cache类型Memory Cache和Disk Cache分别进行介绍。样例代码取自Android开发者站。
1/2:Memory Cache(内存中的Cache)
Memory Cache使用内存来为应用程序提供Cache。由于内存的读写速度非常快,所以我们应该优先使用它(相对于下面将介绍的Disk Cache来说)。
Android中提供了LruCache类来进行Memory Cache的管理(该类是在Android 3.1时推出的,但我们可以使用android -support-v4.jar的兼容包来对低版本的手机提供支持)。
提示:有人习惯使用SoftReference和WeakReference来做Memory Cache,但谷歌官方不建议这么做。因为自从Android2.3之后,Android中的GC变得更加积极,导致这种做法中缓存的Bitmaps非常容易被回收掉;另外,在Android3.0之前,Bitmap的数据是直接分配在native memory中,它的释放是不受dalvik控制的,因此更容易导致内存的溢出。如果你喜欢简单粗暴的总结,那就是:反正不要用这种方法来管理Memory Cache。
下面我们看一段为Bitmap设置LruCache的代码:
01
private
LruCache<String, Bitmap> mMemoryCache;
02
03
@Override
04
protected
void
onCreate(Bundle savedInstanceState) {
05
...
06
// 获取虚拟机可用内存(内存占用超过该值的时候,将报OOM异常导致程序崩溃)。最后除以1024是为了以kb为单位
07
final
int
maxMemory = (
int
) (Runtime.getRuntime().maxMemory() /
1024
);
08
09
// 使用可用内存的1/8来作为Memory Cache
10
final
int
cacheSize = maxMemory /
8
;
11
12
mMemoryCache =
new
LruCache<String, Bitmap>(cacheSize) {
13
@Override
14
protected
int
sizeOf(String key, Bitmap bitmap) {
15
// 重写sizeOf()方法,使用Bitmap占用内存的kb数作为LruCache的size
16
return
bitmap.getByteCount() /
1024
;
17
}
18
};
19
...
20
}
21
22
public
void
addBitmapToMemoryCache(String key, Bitmap bitmap) {
23
if
(getBitmapFromMemCache(key) ==
null
) {
24
mMemoryCache.put(key, bitmap);
25
}
26
}
27
28
public
Bitmap getBitmapFromMemCache(String key) {
29
return
mMemoryCache.get(key);
30
}
提示:在以上代码中,我们使用了可用内存的1/8来提供给Memory Cache,我们简单分析一下这个值。一个普通屏幕尺寸、hdpi的手机的可用内存为32M,那么他的Memory Cache为32M/8=4M。通常hdpi的手机为480*800像素,它一个全屏Bitmap占用内存为480*800*4B=1536400B≈1.5M。那么4M的内存为大约2.5个屏幕大小的bitmap提供缓存。同理,一个普通尺寸、xhdpi大小的720*1280的手机可以为大约2.2个屏幕大小的bitmap提供缓存。
当一个ImageView需要设置一个bitmap的时候,LruCache会进行检查,如果它已经缓存了相应的bitmap,它就直接取出来并设置给这个ImageView;否则,他将启动一个后台线程加载这个Bitmap:
01
public
void
loadBitmap(
int
resId, ImageView imageView) {
02
final
String imageKey = String.valueOf(resId);
03
04
final
Bitmap bitmap = getBitmapFromMemCache(imageKey);
05
if
(bitmap !=
null
) {
06
mImageView.setImageBitmap(bitmap);
07
}
else
{
08
mImageView.setImageResource(R.drawable.image_placeholder);
09
BitmapWorkerTask task =
new
BitmapWorkerTask(mImageView);
10
task.execute(resId);
11
}
12
}
BitmapWorkerTask在加载完成后,通过前面的addBitmapToMemoryCache()方法把这个bitmap进行缓存:
01
class
BitmapWorkerTask
extends
AsyncTask<Integer, Void, Bitmap> {
02
...
03
// 后台加载Bitmap
04
@Override
05
protected
Bitmap doInBackground(Integer... params) {
06
final
Bitmap bitmap = decodeSampledBitmapFromResource(
07
getResources(), params[
0
],
100
,
100
));
08
addBitmapToMemoryCache(String.valueOf(params[
0
]), bitmap);
09
return
bitmap;
10
}
11
...
12
}
- cache-1
- Cache工作原理-1
- Cache工作原理-1
- Cache Fusion (1)
- Cache工作原理-1
- Spring3.1 Cache注解
- Spring3.1 Cache注解
- Spring3.1 Cache注解
- Spring3.1 Cache注解
- Spring3.1 Cache注解
- Spring3.1 Cache注解
- Spring3.1 Cache注解
- Spring3.1 Cache注解
- Spring3.1 Cache注解
- Spring3.1 Cache注解
- Spring3.1 Cache注解
- Spring4.1 cache 应用
- Spring3.1 Cache注解
- Java RandomAccessFile用法(转)
- Android 实现图片的圆角 (转)
- 百度地图-设置中性点坐标
- An internal error occurred during: "Redeploy". Cannot change deployment state from ERROR to REDEPLOY
- 百度地图SDK5-基本设置
- cache-1
- Async Task的使用详解
- cache-2
- ion学习
- git-appraise
- 4种安卓自带的HTTP通讯方式(只是例子,网络通讯就随便写在主线)
- cp的使用注意事项
- Android有效解决加载大图片时内存溢出的问题
- java移位运算符:<<(左移)、>>(带符号右移)和>>>(无符号右移)