Android 应用中需要显示网络图片时,图片的加载过程较为耗时,因此加载过程使用线程池进行管理,

同时使用本地缓存保存图片(当来回滚动ListView时,调用缓存的图片),这样加载和显示图片较为友好。

参考:http://www.eoeandroid.com/thread-210082-1-1.html?_dsign=1b202888

核心代码:

1. MainActivity

package com.desmand.threadtest;

import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.ImageView; import java.io.IOException;
import java.net.URL;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; public class MainActivity extends AppCompatActivity { @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); loadImage("http://www.baidu.com/img/baidu_logo.gif", R.id.imageView1, 1);
loadImage("http://cn.bing.com/sa/simg/bing_p_rr_teal.ico", R.id.imageView2, 2);
loadImage("http://cache.soso.com/30d/img/web/logo.gif", R.id.imageView3, 3);
loadImage("http://csdnimg.cn/www/images/csdnindex_logo.gif", R.id.imageView4, 4);
loadImage("http://images.cnblogs.com/logo_small.gif", R.id.imageView5, 5);
} // 4. 引入线程池,并引入内存缓存功能,并对外部调用封装了接口,简化调用过程
private AsyncImageLoader asyncImageLoader = new AsyncImageLoader(); private void loadImage(String url, final int id, final int count){ // 如果缓存过就会从缓存中取出图像,ImageCallback接口中方法也不会被执行
Drawable cacheImage = asyncImageLoader.loadDrawable(url, new AsyncImageLoader.ImageCallback() { // 请参见实现:如果第一次加载url时下面方法会执行
@Override
public void imageLoaded(Drawable imageDrawable) {
((ImageView) findViewById(id)).setImageDrawable(imageDrawable);
Log.i("test", "1count: " + count);
}
}); if (cacheImage != null){
((ImageView) findViewById(id)).setImageDrawable(cacheImage);
Log.i("test", "2count: " + count);
}
} // 3. 引入线程池来管理多线程
// private Handler handler3 = new Handler();
// private ExecutorService executorService = Executors.newFixedThreadPool(5);
//
// private void loadImage(final String url, final int id, final int count) {
// executorService.submit(new Runnable() {
// @Override
// public void run() {
// final Drawable drawable;
// try {
// drawable = Drawable.createFromStream(new URL(url).openStream(), "image.png");
//
// //模拟网络延时
// SystemClock.sleep(2000);
// handler3.post(new Runnable() {
// @Override
// public void run() {
// ((ImageView) MainActivity.this.findViewById(id)).setImageDrawable(drawable);
// Log.i("test", "count: " + count);
// }
// });
// } catch (IOException e) {
// e.printStackTrace();
// }
// }
// });
// } // 2. 采用handler+Thread模式实现多线程异步加载
// final Handler handler2 = new Handler() {
// @Override
// public void handleMessage(Message msg) {
// ((ImageView) MainActivity.this.findViewById(msg.arg1)).setImageDrawable((Drawable) msg.obj);
// Log.i("test", "count: " + msg.arg2);
// }
// };
//
// private void loadImage(final String url, final int id, final int count) {
// Thread thread = new Thread() {
// @Override
// public void run() {
// Drawable drawable = null;
// try {
// drawable = Drawable.createFromStream(new URL(url).openStream(), "image.png");
// } catch (IOException e) {
// Log.d("test", e.getMessage());
// }
//
// // 模拟网络延时
// SystemClock.sleep(2000);
//
// Message message = handler2.obtainMessage();
// message.arg1 = id;
// message.obj = drawable;
// message.arg2 = count;
// handler2.sendMessage(message);
// }
// };
// thread.start();
// } // 1. 主线程直接加载,不可用
// private Handler handler = new Handler();
// private void loadImage(final String url, final int id, final int count) {
// handler.post(new Runnable() {
// public void run() {
// Drawable drawable = null;
// try {
// drawable = Drawable.createFromStream(new URL(url).openStream(), "image.gif");
// } catch (IOException e) {
// Log.d("test", e.getMessage());
// }
//
// if (drawable == null) {
// Log.d("test", "null drawable");
// } else {
// Log.d("test", "not null drawable");
// }
//
// // 为了测试缓存而模拟的网络延时
// SystemClock.sleep(2000);
//
// ((ImageView) MainActivity.this.findViewById(id)).setImageDrawable(drawable);
// }
// });
// } }

2. AsyncImageLoader

package com.desmand.threadtest;

import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.SystemClock; import java.io.IOException;
import java.lang.ref.SoftReference;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; /**
* Created by fansen on 2016/02/23.
*/
public class AsyncImageLoader {
// 为了加快速度,在内存中开启缓存(主要应用于重复图片较多时,或者同一个图片要多次被访问,比如在ListView时来回滚动)
public Map<String, SoftReference<Drawable>> imageCache = new HashMap<>();
private ExecutorService executorService = Executors.newFixedThreadPool(5);
private Handler handler = new Handler(); /**
* @param imageUrl 图像url地址
* @param callback 回调接口
* @return 返回内存中缓存的图像,第一次加载返回null
*/
public Drawable loadDrawable(final String imageUrl, final ImageCallback callback) { // 如果缓存过就从缓存中取出数据
if (imageCache.containsKey(imageUrl)) {
SoftReference<Drawable> softReference = imageCache.get(imageUrl);
if (softReference.get() != null) {
return softReference.get();
}
} // 缓存中没有图像,则从网络上取出数据,并将取出的数据缓存到内存中
executorService.submit(new Runnable() {
@Override
public void run() {
final Drawable drawable = loadImageFromUrl(imageUrl);
imageCache.put(imageUrl, new SoftReference<>(drawable)); handler.post(new Runnable() {
@Override
public void run() {
callback.imageLoaded(drawable);
}
});
}
}); return null;
} // 从网络上取数据方法
protected Drawable loadImageFromUrl(String imageUrl) {
try {
// 测试时,模拟网络延时,实际时这行代码不能有
SystemClock.sleep(2000);
return Drawable.createFromStream(new URL(imageUrl).openStream(), "image.png");
} catch (IOException e) {
e.printStackTrace();
}
return null;
} //对外界开放的回调接口
public interface ImageCallback {
//注意 此方法是用来设置目标对象的图像资源
void imageLoaded(Drawable imageDrawable); } }

Android 多线程 异步加载的更多相关文章

  1. Android图片异步加载之Android-Universal-Image-Loader

    将近一个月没有更新博客了,由于这段时间以来准备毕业论文等各种事务缠身,一直没有时间和精力沉下来继续学习和整理一些东西.最近刚刚恢复到正轨,正好这两天看了下Android上关于图片异步加载的开源项目,就 ...

  2. Android图片异步加载之Android-Universal-Image-Loader(转)

    今天要介绍的是Github上一个使用非常广泛的图片异步加载库Android-Universal-Image-Loader,该项目的功能十分强大,可以说是我见过的目前功能最全.性能最优的图片异步加载解决 ...

  3. Android 图片异步加载的体会,SoftReference已经不再适用

      在网络上搜索Android图片异步加载的相关文章,目前大部分提到的解决方案,都是采用Map<String, SoftReference<Drawable>>  这样软引用的 ...

  4. C# 多线程 异步加载 窗体

    C# 多线程 异步加载 窗体 分类: C#2014-05-28 16:57 1286人阅读 评论(0) 收藏 举报 异步加载 我们在使用 windowform 编程的时候,我们或许可能会越到,各种在窗 ...

  5. [Android] Android 用于异步加载 ContentProvider 中的内容的机制 -- Loader 机制 (LoaderManager + CursorLoader + LoaderManager.LoaderCallbacks)

    Android 用于异步加载 ContentProvider 中的内容的机制 -- Loader 机制 (LoaderManager + CursorLoader + LoaderManager.Lo ...

  6. android 网络异步加载数据进度条

    ProgressDialog progressDialog = null; public static final int MESSAGETYPE = 0; private void execute( ...

  7. Android开发--异步加载

    因为移动端软件开发思维模式或者说是开发的架构其实是不分平台和编程语言的,就拿安卓和IOS来说,他们都是移动前端app开发展示数据和用户交互数据的数据终端,移动架构的几个大模块:UI界面展示.本地数据可 ...

  8. [置顶] Android图片异步加载之Android-Universal-Image-Loader

    将近一个月没有更新博客了,由于这段时间以来准备毕业论文等各种事务缠身,一直没有时间和精力沉下来继续学习和整理一些东西.最近刚刚恢复到正轨,正好这两天看了下Android上关于图片异步加载的开源项目,就 ...

  9. Android图片异步加载框架Android-Universal-Image-Loader

    版权声明:本文为博主原创文章,未经博主允许不得转载. Android-Universal-Image-Loader是一个图片异步加载,缓存和显示的框架.这个框架已经被很多开发者所使用,是最常用的几个 ...

随机推荐

  1. VC++添加工具栏

    VC添加工具栏 方法一:添加ICON图标 1. 新建一个基于对话框的项目:Test 2. 在类CTestDlg中, 添加两个变量: CToolBarCtrl m_ToolBar1; CImageLis ...

  2. 第一部分实现功能:使用一个TabControl和一个Memo和TDictionary类实现文本临时存储

    效果图: 一期功能概要: a.双击tab关闭tab,双击tab右边空白添加tab(标题为以hhnnsszzz的时间格式命名) b.切换tab将数据存入dictionary,key为标题,value为m ...

  3. MVC4升级MVC5 异常处理

    使用过程中的一些烦人的事情,权当这篇文章是MVC4升级MVC5的异常合集吧,后期不定期更新. 在这里你可以看到ASP.NET MVC的发展历程以及你需要的版本和目前最稳定的版本.戳ASP.NET MV ...

  4. 2014年度辛星html教程夏季版第七节

    经过前面六节的学习,我们大致清楚了HTML教程中的基础内容,那么接下来我们开始继续向后推进,可以说,下面我们介绍一下HTML中的区块. ***************区块*************** ...

  5. iOS8中的UIActionSheet添加UIDatePicker后,UIDatePicker不显示问题

    解决方法:   IOS8以前: UIActionSheet* startsheet = [[UIActionSheet alloc] initWithTitle:title delegate:self ...

  6. Mongodb使用总结

    学习Mongodb已经有半年多了,为啥学习它,工作需要啊.好了,废话不说,总结在实际项目应用中的几点问题. 学习总结 首先,mongodb基本上既照顾到了sql某些语法,又有nosql的许多优点.入门 ...

  7. this、call和apply

    this call apply this 和其他语言不同,JavaScript的this总是指向一个对象,而具体指向哪个对象是在运行时基于函数的执行环境动态绑定的,而非函数被声明时的环境. this的 ...

  8. posix和system v有什么区别/?

    posix和system v有什么区别/?现在在应用时应用那一标准浮云484212 | 浏览 243 次 2014-11-06 10:362014-11-19 22:36 最佳答案们是有关信号量的两组 ...

  9. 玩转AWS CloudWatch微信告警

    做海外业务时大多使用亚马逊 AWS 服务,配套AWS 监控 CloudWatch 功能强大,如果能和微信结合就更棒了.现在分享下如何玩转 CloudWatch 微信通知. AWS EC2 云主机配套的 ...

  10. TC SRM 607 DIV2

    求拼接完成后的字符串包含的子回文串的数目,一开始还用暴力去做,想都不用想 肯定超时了. 复习了一下求最长子回文串的算法,发现可以类似解决. 给相邻字符之间添加一个'@'字符,这样所有的回文串都是奇数长 ...