Android:异步加载图片
我们知道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有两个好处:
- 方便实现异步通信,不需使用 “任务线程(如继承Thread类) + Handler”的复杂组合
- 节省资源,采用线程池的缓存线程 + 复用线程,避免了频繁创建 & 销毁线程所带来的系统资源开销
进阶:异步加载图片的优化
问题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对象设置属性时,以图片的url
为key
,设置为图片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:异步加载图片相关推荐
- wemall app商城源码中基于JAVA的Android异步加载图片管理器代码
wemall doraemon是Android客户端程序,服务端采用wemall微信商城,不对原商城做任何修改,只需要在原商城目录下上传接口文件即可完成服务端的配置,客户端可随意定制修改.本文分享其中 ...
- android异步加载图片并缓存到内存和sd卡上,Android批量图片加载经典系列——采用二级缓存、异步加载网络图片...
http://www.cnblogs.com/jerehedu/p/4560119.html 2015-06-08 09:20 by 杰瑞教育, 232 阅读, 1 评论, 收藏, 编辑一.问题描述 ...
- 演化理解 Android 异步加载图片
引用:http://www.cnblogs.com/ghj1976/archive/2011/05/06/2038738.html 下面测试使用的layout文件: 简单来说就是 LinearLayo ...
- Android 异步加载图片分析
研究了android从网络上异步加载图像,现总结如下: (1)由于android UI更新支持单一线程原则,所以从网络上取数据并更新到界面上,为了不阻塞主线程首先可能会想到以下方法. 在主线程中new ...
- android图片异步加载图片,Android 异步加载图片分析总结
研究了android从网络上异步加载图像,现总结如下: (1)由于android UI更新支持单一线程原则,所以从网络上取数据并更新到界面上,为了不阻塞主线程首先可能会想到以下方法. 在主线程中new ...
- android 异步加载图片总结
一Handler+Runnable模式 我们先看一个并不是异步线程加载的例子,使用 Handler+Runnable模式. 这里为何不是新开线程的原因请参看这篇文章:Android Runnable ...
- android 异步加载图片缩略图
建一个AsyncLoadedImage类继承AsyncTask异步加载类,调用publishProgress方法更新onProgressUpdate贮存缩略图信息到Adapter.监听Adapter ...
- Android实现ListView异步加载图片
转: http://www.iteye.com/topic/685986 ListView异步加载图片是非常实用的方法,凡是是要通过网络获取图片资源一般使用这种方法比较好,用户体验好,下面就说实现方法 ...
- android开发小技巧:实现listview异步加载图片
2019独角兽企业重金招聘Python工程师标准>>> 针对listview异步加载图片这个问题,麦子学院android开发老师讲了一种非常实用的方法,麦子学院android开发老师 ...
最新文章
- 文巾解题 596. 超过5名学生的课
- CentOs下搭建GitLab
- Vux+Cordova打包的安卓App实现微信分享朋友和朋友圈
- mysql 数据库操作类_【数据库操作类】10个php操作数据库类下载
- oracle 二级排序,Oracle基础(二)之排序(order by)、限定查询(where)
- python的namedtuple
- 基于Flume的美团日志收集系统
- 史上最经典Java入门基础视频,没有之一!
- Keil5安装教程最快方法(C51与MDK共存)
- 01-AHP层次分析法
- 关于ASO优化刷榜、冲榜、维榜、锁榜科普百科
- Oracle导出表结构(含表名、字段名、数据类型、是否为空、字段说明)至Excel(简单详细)sql语句的形式
- springboot banner制作
- python列表反向查询_Python反向索引查询
- PX4、APM无人机仿真连接QGC地面站记录(udp连接、更改home点等)
- GPS 入门 8 —— GPS定位基本原理浅析
- 阿里P8耗时3年,总结的Java面试复盘手册,带你挑战50万年薪
- 第 17 章 设计模式(3 装饰者模式)
- c语言read有什么作用,c语言read函数读到什么结束
- visual studio code无法生成可执行文件