我们知道Android为了不阻塞UI线程(main线程),不允许在非UI线程中进行UI操作以及网络请求等操作,为了不阻塞UI,我们往往就要进行异步加载.

我们以异步加载图片为例子,来学习一下异步加载

方法一:Thread+Handler+Message

1.我们新建线程,在线程中获取图片(Bitmap对象)

new Thread() {@Overridepublic void run() {super.run();try {//Android中非主线程无法在线程中更新ui,可通过Handler把数据传递到主线程Bitmap bitmap = getBitmapFromUrl(url);//新建Message对象作为载体Message message = Message.obtain();//将Bitmap对象与消息绑定message.obj = bitmap;//通过Handler发送消息mHandler.sendMessage(message);} catch (IOException e) {e.printStackTrace();} catch (InterruptedException e) {e.printStackTrace();}}}.start();

2.新建Handler用来传递消息,重写handleMessage方法,从Message中取出图片,并设置给ImageView.

 private Handler mHandler = new Handler() {@Overridepublic void handleMessage(@NonNull Message msg) {super.handleMessage(msg);if (mImageView.getTag().equals(mUrl))  //只有ImageView的tag为当前url时,才进行设置mImageView.setImageBitmap((Bitmap) msg.obj);}};

方法二:AsyncTask

1.新建一个loadIMageAsynTask类并继承AsynTask,重写doInBackgroud和onPostExecute方法


public class loadImageAsynTask extends AsyncTask<String, Void, Bitmap> {//Params,Progress,Resultprivate ImageView mImageView;private String mUrl;public loadImageAsynTask(ImageView imageView, String url) {mImageView = imageView;mUrl = url;}//在doInBackground方法中获取Bitmap对象,并返回@Overrideprotected Bitmap doInBackground(String... urls) {Bitmap bitmap = null;try {//从网络上获取图片bitmap = getBitmapFromUrl(urls[0]);if (bitmap != null) {//将下载好的图片保存到LruCache中smLruCache.put(urls[0], bitmap);}} catch (IOException e) {e.printStackTrace();}return bitmap;}//在onPostExecute方法中将Bitmap对象设置给ImageView@Overrideprotected void onPostExecute(Bitmap bitmap) {super.onPostExecute(bitmap);if (mImageView.getTag().equals(mUrl))mImageView.setImageBitmap(bitmap);}}

与Thread+Handler对比,AsyncTask有两个好处:

  1. 方便实现异步通信,不需使用 “任务线程(如继承Thread类) + Handler”的复杂组合
  2. 节省资源,采用线程池的缓存线程 + 复用线程,避免了频繁创建 & 销毁线程所带来的系统资源开销

进阶:异步加载图片的优化

问题1:

由于我们的模拟器网速很快,当我们加载上下滑动图片时不会发生什么问题,但是当我们网速很慢时(我们可以在获取图片时Sleep一秒来模拟网速慢的情况),我们就会发现当item 1,item 2,item 3都加载后我们加载item 4时,并不会直接在item 4 上设置image 4,而是先设置的image 1,image 2, image 3,再设置的image 4.

解决办法:为ImageView设置Tag

1.为View对象设置属性时,以图片的urlkey,设置为图片Tag.

viewHolder.ivIcon.setTag(mList.get(i).getNewsIconUrl());

2.在获得图片(Bitmap)后,设置给ImageView时,先进行判断

if (mImageView.getTag().equals(mUrl))mImageView.setImageBitmap(bitmap);

问题2:

我们每次滑动时,都是从网络重新获取图片,这对于用户来说,很耗流量.

解决办法:使用LruCache

1.新建LruCache,并重写sizeof方法,返回每次缓存的图片大小

mLruCache = new LruCache<String, Bitmap>(cacheSize) {@Overrideprotected int sizeOf(String key, Bitmap value) {//在每次存入缓存中调用,告诉我们的系统存入的对象有多大return value.getByteCount();}};

2.每次从网络上获取图片后,加入到缓存

       //从网络上获取图片bitmap = getBitmapFromUrl(urls[0]);if (bitmap != null) {//将下载好的图片保存到LruCache中smLruCache.put(urls[0], bitmap);}

3.如果缓存中有就从缓存中取,缓存中没有再发送网络请求获取图片

       Bitmap bitmap = null;//从缓存中取出对应的图片,如果缓存中没有,我们就从网络中去下载bitmap = mLruCache.get(urlString);if (bitmap == null) {new loadImageAsynTask(imageView, urlString).execute(urlString);} else {imageView.setImageBitmap(bitmap);}

Android异步加载图片源码:https://github.com/wantao666/AndroidDemo/tree/master/SynTask

Android:异步加载图片相关推荐

  1. wemall app商城源码中基于JAVA的Android异步加载图片管理器代码

    wemall doraemon是Android客户端程序,服务端采用wemall微信商城,不对原商城做任何修改,只需要在原商城目录下上传接口文件即可完成服务端的配置,客户端可随意定制修改.本文分享其中 ...

  2. android异步加载图片并缓存到内存和sd卡上,Android批量图片加载经典系列——采用二级缓存、异步加载网络图片...

    http://www.cnblogs.com/jerehedu/p/4560119.html 2015-06-08 09:20 by 杰瑞教育, 232 阅读, 1 评论, 收藏, 编辑一.问题描述 ...

  3. 演化理解 Android 异步加载图片

    引用:http://www.cnblogs.com/ghj1976/archive/2011/05/06/2038738.html 下面测试使用的layout文件: 简单来说就是 LinearLayo ...

  4. Android 异步加载图片分析

    研究了android从网络上异步加载图像,现总结如下: (1)由于android UI更新支持单一线程原则,所以从网络上取数据并更新到界面上,为了不阻塞主线程首先可能会想到以下方法. 在主线程中new ...

  5. android图片异步加载图片,Android 异步加载图片分析总结

    研究了android从网络上异步加载图像,现总结如下: (1)由于android UI更新支持单一线程原则,所以从网络上取数据并更新到界面上,为了不阻塞主线程首先可能会想到以下方法. 在主线程中new ...

  6. android 异步加载图片总结

    一Handler+Runnable模式 我们先看一个并不是异步线程加载的例子,使用 Handler+Runnable模式. 这里为何不是新开线程的原因请参看这篇文章:Android Runnable ...

  7. android 异步加载图片缩略图

    建一个AsyncLoadedImage类继承AsyncTask异步加载类,调用publishProgress方法更新onProgressUpdate贮存缩略图信息到Adapter.监听Adapter ...

  8. Android实现ListView异步加载图片

    转: http://www.iteye.com/topic/685986 ListView异步加载图片是非常实用的方法,凡是是要通过网络获取图片资源一般使用这种方法比较好,用户体验好,下面就说实现方法 ...

  9. android开发小技巧:实现listview异步加载图片

    2019独角兽企业重金招聘Python工程师标准>>> 针对listview异步加载图片这个问题,麦子学院android开发老师讲了一种非常实用的方法,麦子学院android开发老师 ...

最新文章

  1. 文巾解题 596. 超过5名学生的课
  2. CentOs下搭建GitLab
  3. Vux+Cordova打包的安卓App实现微信分享朋友和朋友圈
  4. mysql 数据库操作类_【数据库操作类】10个php操作数据库类下载
  5. oracle 二级排序,Oracle基础(二)之排序(order by)、限定查询(where)
  6. python的namedtuple
  7. 基于Flume的美团日志收集系统
  8. 史上最经典Java入门基础视频,没有之一!
  9. Keil5安装教程最快方法(C51与MDK共存)
  10. 01-AHP层次分析法
  11. 关于ASO优化刷榜、冲榜、维榜、锁榜科普百科
  12. Oracle导出表结构(含表名、字段名、数据类型、是否为空、字段说明)至Excel(简单详细)sql语句的形式
  13. springboot banner制作
  14. python列表反向查询_Python反向索引查询
  15. PX4、APM无人机仿真连接QGC地面站记录(udp连接、更改home点等)
  16. GPS 入门 8 —— GPS定位基本原理浅析
  17. 阿里P8耗时3年,总结的Java面试复盘手册,带你挑战50万年薪
  18. 第 17 章 设计模式(3 装饰者模式)
  19. c语言read有什么作用,c语言read函数读到什么结束
  20. visual studio code无法生成可执行文件

热门文章

  1. AcWing 1143. 联络员
  2. STM32 固件库,CMSIS 标准,STM32Cube
  3. 系统架构——系统流程图和程序流程图的区别
  4. php创建扑克牌,利用php模拟分发扑克牌(无聊之作)
  5. FLASH AS3相册播放器
  6. sata接口测试软件,SATA接口一致性测试,眼图测试
  7. 中创软件银行信贷管理SOA解决方案
  8. 有什么软件可以修改图片尺寸?分享给你这款图片改大小工具
  9. 【论文推荐】了解《机器翻译》必看的6篇论文(附打包下载地址)
  10. SAP的新T台:在中国站稳脚跟