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是一个图片异步加载,缓存和显示的框架.这个框架已经被很多开发者所使用,是最常用的几个 ...
随机推荐
- 大型B/S系统技术总结(不断更新)
看了<淘宝技术这十年>和<大型网站系统与Java中间件实践>这些书,对大型B/S系统的构建越来越感兴趣,于是尝试收集和总结一些常用的技术手段.不过大型网站的架构是根据业务需求不 ...
- 006.Compile方法
Delphi procedure Compile; 类型:procedure 可见性:public 所在单元:System.RegularExpressionsCore 父类:TPerlRegEx 此 ...
- [数据库连接字符串] Access 连接字符串
[数据库连接字符串] Access 连接字符串 //ODBC 标准安全策略 Driver={Microsoft Access Driver (*.mdb)};Dbq=C:\mydatabase.mdb ...
- python模块之os和os.path模块
1.os模块os.listdir(dirname) 列出dirname下的目录和文件os.getcwd()函数得到当前工作目录,即当前Python脚本工作的目录路径.os.getenv()和os.pu ...
- ubuntu terminal 介绍及相关命令
ubuntu的terminal 1.调出方法 windows键+T 2.终端显示内容 3. 查看当前所在目录的绝对路径--pwd命令 eg1: eg2: linux严格区分大小写 4. 更改/进入目录 ...
- 几个不常见但非常出色的 .NET 开源库
NLog NLog 目前最为出色的 .NET 日志库,非常容易配置,且极具灵活性.最重要的是与 log4net 相比,NLog 的开发很活跃.顺带提一句,NLog 完全兼容 Mono. Mono.Ce ...
- Yours 的博客开张啦!
虽然申请博客已经1个月了,但是一直没有来写,没办法,题都刷不完,哪有心思写啊``` 现在集训终于完了,有了属于自己的时间了.所以该把以前做的题,学的算法好好的整理整理了.一来顺顺思路,二来也可以给后来 ...
- Firefly 性能测试 报告
原地址:http://bbs.gameres.com/thread_223724.html Firefly 性能测试 主要考虑点 网络IO的并发 进程间通信压力 数据读写压力 测试机配置: 操作系统 ...
- StreamCQL
StreamCQLhttps://github.com/HuaweiBigData/StreamCQL http://blog.csdn.net/viewcode/article/details/90 ...
- SPRING IN ACTION 第4版笔记-第八章Advanced Spring MVC-004-Pizza例子的用户流程(flowExecutionKey、_eventId_phoneEntered、flowExecutionUrl )
一. 1. 2. 3.customer-flow.xml 自己定义customer,最后output <?xml version="1.0" encoding="U ...