Android 多线程 异步加载
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 多线程 异步加载的更多相关文章
- Android图片异步加载之Android-Universal-Image-Loader
将近一个月没有更新博客了,由于这段时间以来准备毕业论文等各种事务缠身,一直没有时间和精力沉下来继续学习和整理一些东西.最近刚刚恢复到正轨,正好这两天看了下Android上关于图片异步加载的开源项目,就 ...
- Android图片异步加载之Android-Universal-Image-Loader(转)
今天要介绍的是Github上一个使用非常广泛的图片异步加载库Android-Universal-Image-Loader,该项目的功能十分强大,可以说是我见过的目前功能最全.性能最优的图片异步加载解决 ...
- Android 图片异步加载的体会,SoftReference已经不再适用
在网络上搜索Android图片异步加载的相关文章,目前大部分提到的解决方案,都是采用Map<String, SoftReference<Drawable>> 这样软引用的 ...
- C# 多线程 异步加载 窗体
C# 多线程 异步加载 窗体 分类: C#2014-05-28 16:57 1286人阅读 评论(0) 收藏 举报 异步加载 我们在使用 windowform 编程的时候,我们或许可能会越到,各种在窗 ...
- [Android] Android 用于异步加载 ContentProvider 中的内容的机制 -- Loader 机制 (LoaderManager + CursorLoader + LoaderManager.LoaderCallbacks)
Android 用于异步加载 ContentProvider 中的内容的机制 -- Loader 机制 (LoaderManager + CursorLoader + LoaderManager.Lo ...
- android 网络异步加载数据进度条
ProgressDialog progressDialog = null; public static final int MESSAGETYPE = 0; private void execute( ...
- Android开发--异步加载
因为移动端软件开发思维模式或者说是开发的架构其实是不分平台和编程语言的,就拿安卓和IOS来说,他们都是移动前端app开发展示数据和用户交互数据的数据终端,移动架构的几个大模块:UI界面展示.本地数据可 ...
- [置顶] Android图片异步加载之Android-Universal-Image-Loader
将近一个月没有更新博客了,由于这段时间以来准备毕业论文等各种事务缠身,一直没有时间和精力沉下来继续学习和整理一些东西.最近刚刚恢复到正轨,正好这两天看了下Android上关于图片异步加载的开源项目,就 ...
- Android图片异步加载框架Android-Universal-Image-Loader
版权声明:本文为博主原创文章,未经博主允许不得转载. Android-Universal-Image-Loader是一个图片异步加载,缓存和显示的框架.这个框架已经被很多开发者所使用,是最常用的几个 ...
随机推荐
- Javascript的websocket的使用方法
javascript websocket接口 web实现客户端和服务端双向发送消息的方法有: 轮询,客户端定期向服务端请求: 长轮询,客户端定期向服务端请求,服务端只有有信息发送的时候才返回respo ...
- 9.MVC框架开发(关于ActionResult的处理)
1.在Action处理之后,必须有一个返回值,这个返回值必须继承自ActionResult的对象 2.ActionResult,实际就是服务器端响应给客户端的结果 ViewResult(返回视图结果) ...
- Razor语法小记
1.代码块中,<text>标签用来输出,如: @{ <text>sdfsdf</text> } 输出Html: sdfsdf
- zoj 3765
一道区间更新.查询的题: 但是线段树不能做插入: 后来才知道用splay: splay用来做区间查询的话,先将l-1旋转到根节点,然后把r+1旋转到根节点的右节点: 这样的话,根节点的右节点的左子树就 ...
- 最近在折腾VPS(持续完善)
买的某国内vps. 本机环境 Win7-x64 使用官方英文版的putty,用于远程登录linux主机.WinSCP图形界面管理文件. VPS CentOS 6.2 安装 安全狗(safedog.cn ...
- 独立两套DJANGO+CELERY配置(生产+测试)时要注意的一些细节
1,生产的NGINX环境,要指定自己的目录,而不是PROJ默认的. upstream ism_host { server ; } server { listen ; server_name local ...
- 处理MySQL数据库出现大量Locked的一个案例 (转)
本文转自:http://blog.itpub.net/7607759/viewspace-696781/ 做为一款轻量级数据库软件,MySQL在使用过程中遇到访问速度慢,或者无法响应这类的问题,解决方 ...
- Eclipse导入git上的maven web项目 部署
1 Eclipse中导入Git的maven项目 方法1: (1)首先当然是拉代码. 在Eclipse里面有个Git Repositories Exploring.就是Git仓库,clone a git ...
- http://blog.csdn.net/bluejoe2000/article/details/39521405#t9
http://blog.csdn.net/bluejoe2000/article/details/39521405#t9
- Maven如何手动添加jar包到本地Maven仓库
Apache Maven,是一个软件(特别是Java软件)项目管理及自动构建工具,由Apache软件基金会所提供.基于项目对象模型(缩写:POM)概念,Maven利用一个中央信息片断能管理一个项目的构 ...