android 实现图片缓存,android实现缓存图片等数据

package cc.util.cache;

import java.io.Serializable;

import java.util.Objects;

/**

封装网络数据, 将数据的Etag、lastModified获取到, 下次请求的时候提取出来到服务器比对

* Help to wrap byte data which obtains from network, It will work with {@link cc.util.cache.NetChacheManager}

* @author wangcccong

* @version 1.1406

*
create at: Tues, 10 Jun 2014

*/

public class NetByteWrapper implements Serializable {

private final static long serialVersionUID = 1L;

/** data from network */

private byte[] data;

/** data size */

int contentLength;

/** latested modify time */

private long lastModified;

/** ETag: look up HTTP Protocol */

private String ETag;

public NetByteWrapper(byte[] data, long lastModified, String Etag) {

this.data = data;

this.lastModified = lastModified;

this.ETag = Etag;

}

public byte[] getData() {

return data;

}

public void setData(byte[] data) {

this.data = data;

}

public long getLastModified() {

return lastModified;

}

public void setLastModified(long lastModified) {

this.lastModified = lastModified;

}

public String getETag() {

return ETag;

}

public void setETag(String eTag) {

this.ETag = eTag;

}

public int getContentLength() {

return Objects.isNull(data) ? 0 : data.length;

}

}

package cc.util.cache;

import java.lang.ref.ReferenceQueue;

import java.lang.ref.SoftReference;

/**采用软引用方式将数据存放起来

* enclose {@link cc.util.cache.NetByteWrapper} with {@link java.lang.ref.SoftReference}, In order to recycle the memory

* @author wangcccong

* @version 1.1406

*
create at: Tues, 10 Jun. 2014

*/

public class NetByteSoftReference extends SoftReference {

private String key = "";

private long length = 0;

public NetByteSoftReference(String key, NetByteWrapper arg0) {

this(key, arg0, null);

}

public NetByteSoftReference(String key, NetByteWrapper arg0,

ReferenceQueue super NetByteWrapper> arg1) {

super(arg0, arg1);

// TODO Auto-generated constructor stub

this.key = key;

this.length = arg0.getContentLength();

}

public String getKey() {

return key;

}

public long getLength() {

return length;

}

}

package cc.util.cache;

import java.lang.ref.ReferenceQueue;

import java.lang.ref.SoftReference;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.ObjectInputStream;

import java.io.ObjectOutputStream;

import java.util.Iterator;

import java.util.LinkedHashMap;

import java.util.Objects;

/**

* 采用LinkedHashMap自带的LRU 算法缓存数据, 可检测对象是否已被虚拟机回收,并且重新计算当前缓存大小,清除缓存中无用的键值对象(即已经被虚拟机回收但未从缓存清除的数据);

* 默认内存缓存大小为: 4 * 1024 * 1024 可通过通过setMaxCacheSize重新设置缓存大小,可手动清空内存缓存,支持采用内存映射方式读取缓存

*
支持内存缓存和磁盘缓存方式, 通过 {@link cc.util.cache.NetByteWrapper} 支持HTTP缓存 (注:详细参考cc.util.http包)

* @author wangcccong

* @version 1.1406

*
create at: Tues, 10 Jun 2014

*/

public class NetCacheManager {

/** max cache size */

private long MAX_CACHE_SIZE = 4 * 1024 * 1024;

private long cacheSize = 0;

private static NetCacheManager instance = null;

private final ReferenceQueue referenceQueue;

private final LinkedHashMap cacheMap;

private NetCacheManager(){

referenceQueue = new ReferenceQueue();

cacheMap = new LinkedHashMap(16, 0.75f, true) {

private static final long serialVersionUID = -8378285623387632829L;

@Override

protected boolean removeEldestEntry(

java.util.Map.Entry eldest) {

// TODO Auto-generated method stub

boolean shouldRemove = cacheSize > MAX_CACHE_SIZE;

if (shouldRemove) {

cacheSize -= eldest.getValue().getLength();

System.gc();

}

return shouldRemove;

}

};

}

/** singleton model */

public static synchronized NetCacheManager newInstance(){

if (Objects.isNull(instance)) {

instance = new NetCacheManager();

}

return instance;

}

/**

* reset the memory cache size

* @param cacheSize

*/

public void setMaxCacheSize(long cacheSize) {

this.MAX_CACHE_SIZE = cacheSize;

}

/**

* 获取当前内存缓存大小

* @return

*/

public long getCacheSize() {

return cacheSize;

}

/**

* 将数据缓存至内存, 如果http返回的数据不支持缓存则采用此方法,缓存的key一般为请求的url

* @param key

* @param value

*/

public void cacheInMemory(String key, byte[] value) {

this.cacheInMemory(key, value, 0, null);

}

/**

* 将数据缓存至内存, 如果http返回的数据支持缓存则采用此方法

* @param key

* @param value

* @param lastModified

*/

public void cacheInMemory(String key, byte[] value, long lastModified) {

this.cacheInMemory(key, value, lastModified, null);

}

/**

* 将数据缓存至内存, 如果http返回的数据支持缓存则采用此方法

* @param key

* @param value

* @param Etags

*/

public void cacheInMemory(String key, byte[] value, String Etags) {

this.cacheInMemory(key, value, 0, Etags);

}

/**

* 将数据缓存至内存, 如果http返回的数据支持缓存则采用此方法

* @param key

* @param value

* @param lastModified

* @param Etags

*/

private void cacheInMemory(String key, byte[] value, long lastModified, String Etags) {

Objects.requireNonNull(key, "key must not be null");

clearRecycledObject();

NetByteWrapper wrapper = new NetByteWrapper(value, lastModified, Etags);

NetByteSoftReference byteRef = new NetByteSoftReference(key, wrapper, referenceQueue);

cacheMap.put(key, byteRef);

value = null;

wrapper = null;

}

/**

* 缓存至磁盘, 默认不首先缓存到内存

* @param key

* @param value

* @param path

*/

public void cacheInDisk(String key, byte[] value, String path) {

cacheInDisk(key, value, path, false);

}

/**

*

* @param key

* @param value

* @param path

* @param cacheInMemory

*/

public void cacheInDisk(String key, byte[] value, String path, boolean cacheInMemory) {

this.cacheInDisk(key, value, 0, null, path, cacheInMemory);

}

/**

*

* @param key

* @param value

* @param lastModified

* @param Etags

* @param path

* @param cacheInMemory

*/

private void cacheInDisk(String key, byte[] value, long lastModified, String Etags, String path, boolean cacheInMemory) {

if (cacheInMemory) cacheInMemory(key, value, lastModified, Etags);

try (FileOutputStream fos = new FileOutputStream(path);

ObjectOutputStream oos = new ObjectOutputStream(fos)) {

NetByteWrapper wrapper = new NetByteWrapper(value, lastModified, Etags);

oos.writeObject(wrapper);

} catch (Exception e) {

// TODO: handle exception

e.printStackTrace();

}

}

/**

* get {@link cc.util.cache.NetByteWrapper} from memory according to key

* @param key

* @return {@link cc.util.cache.NetByteWrapper}

*/

public NetByteWrapper getFromMemory(String key) {

SoftReference softReference = cacheMap.get(key);

return Objects.nonNull(softReference) ? softReference.get() : null;

}

/**

* get byte[] from memory according to key

* @param context

* @param key

* @return

*/

public byte[] getByteFromMemory(String key) {

NetByteWrapper wrapper = getFromMemory(key);

return Objects.nonNull(wrapper) ? wrapper.getData() : null;

}

/**

* 从磁盘获取数据

* @param path

* @return {@link cc.util.cache.NetByteWrapper}

*/

public NetByteWrapper getFromDisk(String path) {

try (FileInputStream fis = new FileInputStream(path);

ObjectInputStream ois = new ObjectInputStream(fis)) {

NetByteWrapper wrapper = (NetByteWrapper) ois.readObject();

return wrapper;

} catch (Exception e) {

// TODO: handle exception

e.printStackTrace();

return null;

}

}

/**

* 采用内存映射的方式从磁盘获取数据(加快读取缓存的大文件)

* @param path

* @return

*/

public NetByteWrapper getFromDiskByMapped(String path) {

try (FileInputStream fis = new FileInputStream(path);

FileChannel channel= fis.getChannel();

ByteArrayOutputStream baos = new ByteArrayOutputStream()){

MappedByteBuffer mbb = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());

byte[] bts = new byte[1024];

int len = (int) channel.size();

for (int offset = 0; offset < len; offset += 1024) {

if (len - offset > 1024) mbb.get(bts);

else mbb.get((bts = new byte[len - offset]));

baos.write(bts);

}

ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());

ObjectInputStream ois = new ObjectInputStream(bais);

NetByteWrapper wrapper = (NetByteWrapper) ois.readObject();

bais.close();

ois.close();

return wrapper;

} catch (Exception e) {

// TODO: handle exception

e.printStackTrace();

return null;

}

}

/**

* 从磁盘获取缓存的byte[] 数据

* @param path

* @return

*/

public byte[] getByteFromDisk(String path) {

NetByteWrapper wrapper = getFromDisk(path);

return Objects.isNull(wrapper) ? null : wrapper.getData();

}

/**

* 通过内存映射放射从磁盘获取缓存的byte[] 数据

* @param path

* @return

*/

public byte[] getByteFromDiskByMapped(String path) {

NetByteWrapper wrapper = getFromDiskByMapped(path);

return Objects.isNull(wrapper) ? null : wrapper.getData();

}

/**

* calculate the size of the cache memory

*/

private void clearRecycledObject() {

NetByteSoftReference ref = null;

//检测对象是否被回收,如果被回收则从缓存中移除死项

while (Objects.nonNull((ref = (NetByteSoftReference) referenceQueue.poll()))) {

cacheMap.remove(ref.getKey());

}

cacheSize = 0;

Iterator keys = cacheMap.keySet().iterator();

while (keys.hasNext()) {

cacheSize += cacheMap.get(keys.next()).getLength();

}

}

/**

* clear the memory cache

*/

public void clearCache() {

clearRecycledObject();

cacheMap.clear();

System.gc();

System.runFinalization();

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值