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是一个图片异步加载,缓存和显示的框架.这个框架已经被很多开发者所使用,是最常用的几个 ...
随机推荐
- 编写jQuery插件--实现返回顶部插件
国庆过去一周多了,作为IT界的具有严重’工作狂‘性质的宅人,居然还没走出玩耍的心情,拖了程序猿的脚后跟了.最近工作不顺,心情不佳,想吐槽下公司,想了还是厚道点,以彼之道还施彼身,觉得自己也和他们同流合 ...
- MaskedTextBox控件实现输入验证
Mask属性可以验证用户在文本中输入数据的格式 this.maskedTextBox1.Mask = "000000-00000000-000A";//身份证号码18位 this. ...
- asp.net mvc get controller name and action name
@{ var controller = @HttpContext.Current.Request.RequestContext.RouteData.Values["controller&qu ...
- python mongodb MapReduce
# -*- coding: utf-8 -*-import osimport csvimport pymongofrom pymongo import MongoClientfrom bson.cod ...
- Windows下虚拟Linux
andlinux cygwin virtualbox VMware XenServer
- HDU 1059 Dividing(多重背包)
点我看题目 题意: 将大理石的重量分为六个等级,每个等级所在的数字代表这个等级的大理石的数量,如果是0说明这个重量的大理石没有.将其按重量分成两份,看能否分成. 思路 :一开始以为是简单的01背包,结 ...
- 物理地址为20位 如10000H 用段地址*16+偏移地址表示
段地质在cpu中,为16位 段地质*16则变成物理首地址20位,这个物理首地址必定是16的倍数. 偏移地址16位, 则表明一个段的大小为64k. 同时也表明16位地址的寻址能力为64kb
- 如何将Springside4项目转成Eclipse项目
1)下载springside4 官网地址 http://www.springside.org.cn/download.html 2)运行CMD,进入 C:\Documents and Settings ...
- Dagger 2: Step To Step
文/iamwent(简书作者)原文链接:http://www.jianshu.com/p/7505d92d7748著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”. 假设你已经了解 依赖注 ...
- 转:为什么Eclipse中 按 F3 无效
通常是由于自己的 工程 建得不对, 没有声明为 JAVA 或 PHP 类型工程. 例如, PHP 工程的 .project 文件中的内容如果如下, F3 应该就可以起作用了. <?xml ver ...