探秘google开源android项目gallery如何在手机内存有限的情况下缓存手机sdcard的图片或者视频

来源:互联网 发布:网络经营项目 编辑:程序博客网 时间:2024/05/17 04:17

 

 

在开始阅读这篇博文前,需要一点点java基础的储备知识

 

1.ReferenceQueue的作用,我上一篇博文有比较深入的讲解。

 

2.简单了解LRU算法,我在这里推荐两篇快速了解并学习LRU算法的博文链接:

http://blog.csdn.net/Ackarlix/archive/2007/08/26/1759793.aspx

http://liangwj72.iteye.com/blog/123856

 

直接上代码

 

 

 

 

package cn.itcast.camera.gallery;

 

import java.lang.ref.ReferenceQueue;

import java.lang.ref.WeakReference;

import java.util.HashMap;

import java.util.LinkedHashMap;

import java.util.Map;

 

/**

 * LruCache(对象缓冲池)用于缓存对象,有些图片或者视频在界面上显示,如果每次都从数据库去取(图片或视频文件以二进制流的形式存在数据库中),

 * 就会加应用处理的负担

 * ,用LruCache就能解决此问题,只要第一次从数据库中取出,然后把取出的东西放在LRUCache中,之后每次就可以从LRUCache中去取了

 * ,加快访问速度。并有效地节省内存。

 */

public class LruCache<K, V> {

 

//mLruMap:一个简单实现LRU算法的LinkedHashMap

private final HashMap<K, V> mLruMap;

//mWeakMap:保存 弱引用对象Entry

private final HashMap<K, Entry<K, V>> mWeakMap = new HashMap<K, Entry<K, V>>();

//mQueue:记录引用对象已被垃圾回收器回收过的Entry

private ReferenceQueue<V> mQueue = new ReferenceQueue<V>();

 

//设定LruCache固定存储的最大容量

@SuppressWarnings("serial")

public LruCache(final int capacity) {

mLruMap = new LinkedHashMap<K, V>(16, 0.75f, true) {

 

@Override

protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {

//LRU算法最关键的一步,自动清除过期数据,始终保证mLruMap 的size<=capacity,即mLruMap 内存占用总大小<=单个对象所占内存*capacity

return size() > capacity;

}

};

}

 

private static class Entry<K, V> extends WeakReference<V> {

//保存Key值,以便mWeakMap删除已被垃圾回收器回收过的弱引用对象Entry

K mKey;

 

public Entry(K key, V value, ReferenceQueue<V> queue) {

super(value, queue);

mKey = key;

}

}

 

//清空mWeakMap里已被垃圾回收器回收过的Entry(表明Entry所引用的对象已经被垃圾回收器回收,这时需要清除Entry对象本身)

@SuppressWarnings("unchecked")

private void cleanUpWeakMap() {

Entry<K, V> entry = (Entry<K, V>) mQueue.poll();

//一旦垃圾回收器回收该Entry所引用的对象,就从mWeakMap里删除该Entry

while (entry != null) {

mWeakMap.remove(entry.mKey);

entry = (Entry<K, V>) mQueue.poll();

}

}

 

//将对象放入缓存,并保存弱引用

public synchronized V put(K key, V value) {

cleanUpWeakMap();

mLruMap.put(key, value);

Entry<K, V> entry = mWeakMap.put(key, new Entry<K, V>(key, value, mQueue));

return entry == null ? null : entry.get();

}

 

//取得对象

public synchronized V get(K key) {

cleanUpWeakMap();

V value = mLruMap.get(key);

if (value != null)

return value;

Entry<K, V> entry = mWeakMap.get(key);

return entry == null ? null : entry.get();

}

//清空

public synchronized void clear() {

mLruMap.clear();

mWeakMap.clear();

mQueue = new ReferenceQueue<V>();

}

}

 

 

原创粉丝点击