您的位置:首页 > 其它

关于LruCache和图片加载的封装

2016-09-18 13:55 197 查看

前言

LruCache是用来在Android中实现内存缓存的,它是一个泛型类,内部采用LinkedHashMap以强引用的方式存储外界的缓存对象,提供了get和put方法获取和添加缓存对象,当缓存满时,LruCache会移除较早使用的缓存对象,然后再添加新的缓存对象。

//maxMemory方法返回的堆内存的大小,单位是B,在此需要转化为KB
int maxSize = (int) (Runtime.getRuntime().maxMemory() / 1024);
int cacheSize = maxSize/8;
LruCache<String,Bitmap> lruCache = new LruCache<String,Bitmap>(cacheSize){
@Override
protected int sizeOf(String key, Bitmap bitmap) {
return bitmap.getRowBytes()*bitmap.getHeight()/1024;
}

@Override//移除旧缓存时会调用此方法,可以在此完成资源回收
protected void entryRemoved(boolean evicted, String key, Bitmap oldValue, Bitmap newValue) {
super.entryRemoved(evicted, key, oldValue, newValue);
}
};


另外LruCache是线程安全的,实现的方式是采用同步代码块,部分代码如下

public void trimToSize(int maxSize) {
while (true) {
K key;
V value;
synchronized (this) {
if (size < 0 || (map.isEmpty() && size != 0)) {
throw new IllegalStateException(getClass().getName()
+ ".sizeOf() is reporting inconsistent results!");
}

if (size <= maxSize) {
break;
}

Map.Entry<K, V> toEvict = map.eldest();
if (toEvict == null) {
break;
}

key = toEvict.getKey();
value = toEvict.getValue();
map.remove(key);
size -= safeSizeOf(key, value);
evictionCount++;
}

entryRemoved(true, key, value, null);
}
}


图片加载的封装

同步加载

同步加载需要在外部线程中调用,因为可能是耗时的操作

public Bitmap loadBitmap(String url,int reqWidth,int reqHeight){
//判断是否是主线程,是的话抛出异常
if(Looper.myLooper()==Looper.getMainLooper()){
throw new RuntimeException("can't visit network form UI thread")
}
}


异步加载

创建一个Runnable对象,在里面去加载图片,通过Handler发送结果到主线程,然后在线程池里面去执行这个任务,

为什么要采用线程池:如果采用普通的线程,随着列表的滑动可能会产生大量的线程,这样不利于整体效率的提升

如何在子线程中创建Handler

两种方式:

手动调用Looper.prepare和Looper.loop

Looper.prepare();
Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
}
};
Looper.loop();


用主线程的Looper初始化Handler

Handler handler = new Handler(Looper.getMainLooper()){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: