Android 异步任务——AsyncTask (附使用AsyncTask下载图片Demo)
我们编程的时候经常需要处理同步任务和异步任务,在Android里面存在一个特性,就是UI线程是不安全的线程。所谓UI线程不安全也就是我们的主线程(进程启动的第一个线程)不能在线程外操作主线程的资源。因为主线程的资源没有做同步处理。也就是我们一般说的线程同步问题。
我们做Android应用的时候,进程需要在一个子线程执行一些耗时的操作,例如下载、播放等。这种情况我们一般使用Handler和线程结合处理,子线程负责处理耗时操作,然后通知Handler处理UI更新。Handler和子线程结合处理适合对精度控制要求比较高或者任务耗时比较长或者比较反复的情况。除了Handler和线程结合使用,Android也为我们提供了另外一种选择,也就是今天要说的AsyncTask。
AsyncTask内部也是使用了Handler和线程的模式,只是Google把它封装好了。下面我们看看AsyncTask如何使用。
(PS:新建的QQ群,有兴趣可以加入一起讨论:Android群:322599434)
1、android.os.AsyncTask的定义
public abstract class AsyncTask<Params, Progress, Result>
- Params:输入的参数
- Progress:更新的进度,一般用来更新UI的进度信息
- Result:是执行后的返回结果
这些参数都是泛型定义,所以我们可以定义自己的数据类型作为参数,另外如果不需要相关传输,可以传入Void即可。
2、AsyncTask接口
//执行异步任务,启动异步任务需要执行这个接口
public final AsyncTask<Params, Progress, Result> execute(Params... params)
{
return executeOnExecutor(sDefaultExecutor, params);
}
//在execute()被调用后立即执行,可以做一些任务初始化
protected void onPreExecute()
{
}
//在onPreExecute()执行后执行,执行一些耗时操作,此方法将接收输入参数和返回计算结果。
//在执行过程中可以调用publishProgress()来更新进度信息
protected abstract Result doInBackground(Params... params);
//在调用publishProgress(Progress... values)时,回调这个方法,用来更新进度信息
protected void onProgressUpdate(Progress... values)
{
}
//doInBackground执行完后,会回调此方法,用于更新界面信息
protected void onPostExecute(Result result)
{
}
上面是AsyncTask的一些重要接口和方法,可以看出大部分都是空方法还有就是虚函数。我们继承AsyncTask的时候,一般都需要重写上面的方法,方便我们执行相应的操作。
3、AsyncTask例子
下面是我编写的一个使用AsyncTask下载图片的例子,这个例子功能是利用AsyncTask下载一张图片。
private class DownLoad extends AsyncTask<String, Integer, String>
{
//onPreExecute方法在execute()后执行
@Override
protected void onPreExecute()
{
Log.i(TAG, "onPreExecute() enter");
mShowLogTextView.setText("onPreExecute。。。begin downLoad");
} //doInBackground方法内部执行后台任务,不能在里面更新UI,否则有异常。
@Override
protected String doInBackground(String... params)
{
Log.i(TAG, "doInBackground(String... params) enter"); URL imageUrl=null;
try
{
imageUrl=new URL(params[]);
}
catch (MalformedURLException e)
{
e.printStackTrace();
Log.e(TAG, e.getMessage());
}
try
{
//使用HttpURLConnection打开连接
HttpURLConnection urlConn=(HttpURLConnection)imageUrl.openConnection();
urlConn.setDoInput(true);
urlConn.connect();
//将得到的数据转化成InputStream
InputStream is=urlConn.getInputStream();
//将InputStream转换成Bitmap
mDownLoadBtBitmap=BitmapFactory.decodeStream(is);
is.close();
//不能在这里更新UI,否则有异常******
//mNetImageView.setImageBitmap(bitmap);
}catch(IOException e)
{
Log.e(TAG,e.getMessage());
} return "ok";
} //onProgressUpdate方法用于更新进度信息
@Override
protected void onProgressUpdate(Integer... progresses)
{
Log.i(TAG, "onProgressUpdate(Integer... progresses) enter"); mShowLogTextView.setText("onProgressUpdate Downloading...");
} //onPostExecute用于doInBackground执行完后,更新界面UI。
//result是doInBackground返回的结果
@Override
protected void onPostExecute(String result)
{
Log.i(TAG, "onPostExecute(Result result) called");
mShowLogTextView.setText("Down load finish result="+result); mNetImageView.setImageBitmap(mDownLoadBtBitmap);
} //onCancelled方法用于取消Task执行,更新UI
@Override
protected void onCancelled()
{
Log.i(TAG, "onCancelled() called");
mShowLogTextView.setText("onCancelled");
}
}
上面是继承了AsyncTask类,重写了里面相关方法的之类,从上面可以看出AsyncTask主要的操作任务都是放到了doInBackground执行。然后onPostExecute最后更新结果。让AsyncTask开始执行 的方法很简单,只要调用execute并传入相关参数即可。
public void onClick(View v)
{
if (v==mPlayMusicButton)
{
//传入下载图片的地址 mythou
mDownLoad.execute("http://pic.desk.chinaz.com/file/10.11.10/7/jillxs40.jpg");
//mDownLoad.execute("http://www.baidu.com/img/bdlogo.gif");
}
}
这里传入的参数是作为doInBackground方法的参数,这里传入图片的URL,然后执行下载图片操作。下面说说AsyncTask使用的时候需要注意的事情。
- AsyncTask的实例必须在UI线程中创建,并且在UI线程调用execute(Params... params)开始任务。
- 不要手动调用onPreExecute(),doInBackground(Params... params),onProgressUpdate(Progress... values), onPostExecute(Result result)等AsyncTask的回调函数。
- 不能在doInBackground(Params... params)中更改UI组件的信息。
- 一个任务实例只能执行一次,如果执行第二次将会抛出异常。
下面是这个例子执行效果:


AsyncTask的Demo代码下载:点击这里
Edited by mythou
原创博文,转载请标明出处:http://www.cnblogs.com/mythou/p/3191174.html
Android 异步任务——AsyncTask (附使用AsyncTask下载图片Demo)的更多相关文章
- android+nutz后台如何上传和下载图片
android+nutz后台如何上传和下载图片 发布于 588天前 作者 yummy222 428 次浏览 复制 上一个帖子 下一个帖子 标签: 无 最近在做一个基于android的ap ...
- Android异步处理二:使用AsyncTask异步更新UI界面
在<Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面>中,我们使用Thread+Handler的方式实现了异步更新UI界面,这一篇中,我们介绍一种更为简 ...
- Python爬虫获取异步加载站点pexels并下载图片(Python爬虫实战3)
1. 异步加载爬虫 对于静态页面爬虫很容易获取到站点的数据内容,然而静态页面需要全量加载站点的所有数据,对于网站的访问和带宽是巨大的挑战,对于高并发和大访问访问量的站点来说,需要使用AJAX相关的技术 ...
- 将QT开发的界面程序封装成DLL,在VC中成功调用(必须有消息循环,所以使用了QTWinmigrate,附CSDN可下载的Demo)
最近手头的一个项目需要做一个QT界面,并且封装成DLL,然后再动态调用DLL给出的接口函数,使封装在DLL内部的QT界面跑起来,在网上查了很多资料,今天终于成功了,经验不敢独享,因为CSDN给了我很多 ...
- 【转】COCOS2D-X之CCHttpRequest下载图片Demo
#include "pthread.h" #pragma comment(lib,"libcurl_imp.lib") #pragma comment(lib, ...
- Android异步处理系列文章四篇之四 AsyncTask的实现原理
Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面Android异步处理二:使用AsyncTask异步更新UI界面Android异步处理三:Handler+Loope ...
- Android异步处理系列文章四篇之二 使用AsyncTask异步更新UI界面
Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面Android异步处理二:使用AsyncTask异步更新UI界面Android异步处理三:Handler+Loope ...
- Android异步处理四:AsyncTask的实现原理
在<Android异步处理二:使用AsyncTask异步更新UI界面>一文中,我们介绍了如何使用AsyncTask实现异步下载图片,并且更新图片到UI界面的方法.本篇我们将学习Framew ...
- 【转载】Android异步处理系列文章
本博文地址:http://blog.csdn.net/mylzc/article/details/6777767 转载请注明出处. 为了给用户带来良好的交互体验,在Android应用的开发过程中需要把 ...
随机推荐
- IDEA使用笔记(三)——小齿轮的显示和隐藏(Autoscroll from Source)
在玩快捷键的时候,不清楚自己操作了什么,突然间发现——能直接定位到当前可编辑文件的哪个小齿轮,不见了,找了一会也没弄出来,从网上搜索吧!也没看到对应的方法,后来自己耐下心来复盘自己的操作,终于发现了, ...
- bat 批处理脚本定时执行命令
有个需求,需要每天定时执行下某个任务,一天一次.由于工作机器环境问题,没有办法设置windows 定时任务.查找资料并完成如下脚本. 功能:每天定时执行一次任务. 复制如下脚本,到一个test.vbs ...
- 安装CDH5时出错 5.68.168.192.in-addr.arpa domain name pointer bogon.
这个是因为使用的DNS是联通的server,联通会将所有保留的网络地址RFC1918( http://tools.ietf.org/html/rfc1918)都指向"bogon" ...
- word中公式居中编号在最右端
1 显示标尺 2 设置居中制表符 3 在对应位置做标记 首先让公式居中 使用居中制表符在标尺的灰色地带标记位置,1)标记公式位置,鼠标左击 2)标记右边标号位置,注意和右边留有一定边距 4 公式左对齐 ...
- windows下php的各个版本下载地址
windows下php的各个版本 https://windows.php.net/downloads/releases/archives/
- 关系型数据库性能测试参考指标----SQL Server
注:以下指标取自SQL Server自身提供的性能计数器. [@more@] SQL Server 指标名称 指标描述 指标范围 指标单位 1.SQL Server中访问方法(Access Metho ...
- 复习下C 链表操作(单向循环链表、查找循环节点)
循环链表 稍复杂点. 肯能会有0 或 6 字型的单向循环链表. 接下来创建 单向循环链表 并 查找单向循环链表中的循环节点. 这里已6字型单向循环链表为例. //创建 循环链表 Student * ...
- 《深入理解jvm》笔记---第六章
类文件结构 1. Java一次编写,到处执行的基石: Java编译产生的是字节码(bytecode).sun公司和其它虚拟机提供商公布各个平台上的虚拟机.这些虚拟机能够加载和执行这些与平台无关的 ...
- PostgreSQL判断是否为空coalesce
coalesce(expr1,expr2,expr3...) 直到找到一个非null值返回,右边的表达式则不参与运算:若所有为null,返回null. eg:判断json是否包含某属性,若无,则取默认 ...
- 含有按钮的ScrollView在iOS8中无法滚动的解决办法 | ScrollView with UIControl/UIButton subviews not scrollable under iOS 8
转自:http://zcw.me/blogwp/%E5%90%AB%E6%9C%89%E6%8C%89%E9%92%AE%E7%9A%84scrollview%E5%9C%A8ios8%E4%B8%A ...