android handler+线程池+消息队列模式+缓存,android异步图片加载三之handler+线程池+消息队列模式+缓存...

android异步图片加载三之handler+线程池+消息队列模式+缓存

假象现在有这样一个需求:

一个微博客户端或者多媒体客户端需要从服务端拉取一些数据,该数据中包含了很多图片,如果不用异步加载方式,可能会使主线程阻塞导致ANR异常,但是异步加载后如果每次都通过网络去下载图片,性能上会差很多,而且也会浪费流量,导致用户的不满,故现在增加一个缓存用来存储图片,缓存中包含内存存储和sdcard存储。先从缓存中去,在缓存中先从内存中取出,如果内存中没有再从sdcard去,如果sdcard中存在则直接返回该图片资源并放入内存中,如果两者都没有则从网络上下载,下载后并放入sdcard中供下次使用,这样就节约了资源开销,下面是主要代码:

PicManager(用来处理图片的操作):

publicclassPicManager {

privateMap> imgCache ;

privateContext ctx;

publicPicManager(Map> imgCache,Context ctx) {

this.ctx = ctx;

this.imgCache = imgCache;

}

/**

* 从网络上下载

* @param url

* @return

*/

publicBitmap getBitMapFromUrl(String url) {

Bitmap bitmap = null;

URL u =null;

HttpURLConnection conn = null;

InputStream is = null;

try{

u = newURL(url);

conn = (HttpURLConnection)u.openConnection();

is = conn.getInputStream();

bitmap = BitmapFactory.decodeStream(is);

} catch(Exception e) {

e.printStackTrace();

}

returnbitmap;

}

/**

* 从文件中读取

* @return

* @throws Exception

*/

privateBitmap getBitMapFromSDCard(String url)throwsException {

Bitmap bitmap = null;

String filename = MD5Util.getMD5(url);

FileInputStream fis = ctx.openFileInput(filename);

bitmap = BitmapFactory.decodeStream(fis);

returnbitmap;

}

/**

* 从缓存中读取

* @param url

* @return

* @throws Exception

*/

publicBitmap getImgFromCache(String url)throwsException {

Bitmap bitmap = null;

//从内存中读取

if(imgCache.containsKey(url)) {

synchronized(imgCache) {

SoftReference bitmapReference = imgCache.get(url);

if(null!= bitmapReference) {

bitmap = bitmapReference.get();

}

}

} else{//否则从文件中读取

bitmap = getBitMapFromSDCard(url);

//将图片保存进内存中

imgCache.put(url, newSoftReference(bitmap));

}

returnbitmap;

}

/**

* 将图片写入sdcard中

* @param bitmap

* @param url

* @throws Exception

*/

publicvoidwritePic2SDCard(Bitmap bitmap,String url)throwsException {

String filename = MD5Util.getMD5(url);

FileOutputStream fos = ctx.openFileOutput(filename, ctx.MODE_APPEND);

byte[] bitmapByte = PictureUtil.bitmap2Byte(bitmap);

ByteArrayInputStream bis = newByteArrayInputStream(bitmapByte);

intlen =0;

byte[] b =newbyte[bis.available()];

while((len = bis.read(b)) != -1) {

fos.write(b, 0, len);

}

if(null!= bis) {

bis.close();

}

if(null!= fos) {

fos.close();

}

}

}

ImgLoader(用来加在图片):

publicclassImgLoader {

privateMap> imgCache =newHashMap>();

privateContext ctx;

publicImgLoader(Context ctx) {

this.ctx = ctx;

}

privatePicManager manager =newPicManager(imgCache,ctx);

privateHandler handler =newHandler();

privateExecutorService threadPool = Executors.newFixedThreadPool(5);

publicBitmap loadImg(finalString url,finalImgCallback callback) {

//先从缓存中读取图片资源

Bitmap bitmap = null;

try{

bitmap = manager.getImgFromCache(url);;

if(null== bitmap) {

//开启线程从网络上下载

threadPool.submit(newRunnable() {//submit方法确保下载是从线程池中的线程执行

@Override

publicvoidrun() {

finalBitmap bitmapFromUrl = manager.getBitMapFromUrl(url);

try{

manager.writePic2SDCard(bitmapFromUrl,url);

} catch(Exception e) {

e.printStackTrace();

}

handler.post(newRunnable() {

@Override

publicvoidrun() {

callback.refresh(bitmapFromUrl);

}

});

}

});

} else{

}

} catch(Exception e) {

e.printStackTrace();

}

returnbitmap;

}

}

ImgCallback callback是一个接口,用来刷新界面

publicinterfaceImgCallback {

publicvoidrefresh(Bitmap bitmap);

}

最后更新:2017-04-03 19:13:18

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值