我们编程的时候经常需要处理同步任务和异步任务,在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)的更多相关文章

  1. android+nutz后台如何上传和下载图片

    android+nutz后台如何上传和下载图片  发布于 588天前  作者 yummy222  428 次浏览  复制  上一个帖子  下一个帖子  标签: 无 最近在做一个基于android的ap ...

  2. Android异步处理二:使用AsyncTask异步更新UI界面

    在<Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面>中,我们使用Thread+Handler的方式实现了异步更新UI界面,这一篇中,我们介绍一种更为简 ...

  3. Python爬虫获取异步加载站点pexels并下载图片(Python爬虫实战3)

    1. 异步加载爬虫 对于静态页面爬虫很容易获取到站点的数据内容,然而静态页面需要全量加载站点的所有数据,对于网站的访问和带宽是巨大的挑战,对于高并发和大访问访问量的站点来说,需要使用AJAX相关的技术 ...

  4. 将QT开发的界面程序封装成DLL,在VC中成功调用(必须有消息循环,所以使用了QTWinmigrate,附CSDN可下载的Demo)

    最近手头的一个项目需要做一个QT界面,并且封装成DLL,然后再动态调用DLL给出的接口函数,使封装在DLL内部的QT界面跑起来,在网上查了很多资料,今天终于成功了,经验不敢独享,因为CSDN给了我很多 ...

  5. 【转】COCOS2D-X之CCHttpRequest下载图片Demo

    #include "pthread.h" #pragma comment(lib,"libcurl_imp.lib") #pragma comment(lib, ...

  6. Android异步处理系列文章四篇之四 AsyncTask的实现原理

    Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面Android异步处理二:使用AsyncTask异步更新UI界面Android异步处理三:Handler+Loope ...

  7. Android异步处理系列文章四篇之二 使用AsyncTask异步更新UI界面

    Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面Android异步处理二:使用AsyncTask异步更新UI界面Android异步处理三:Handler+Loope ...

  8. Android异步处理四:AsyncTask的实现原理

    在<Android异步处理二:使用AsyncTask异步更新UI界面>一文中,我们介绍了如何使用AsyncTask实现异步下载图片,并且更新图片到UI界面的方法.本篇我们将学习Framew ...

  9. 【转载】Android异步处理系列文章

    本博文地址:http://blog.csdn.net/mylzc/article/details/6777767 转载请注明出处. 为了给用户带来良好的交互体验,在Android应用的开发过程中需要把 ...

随机推荐

  1. java JDK JRE 1.6,1.7,1.8各个版本版本下载链接

    有时想找jdk的某个版本并不太好找,在此给出所有链接及对应的api JavaSE 1.6各个版本 jdk  api http://www.Oracle.com/technetwork/Java/jav ...

  2. class-dump在osx 10.11以后安装方法

      当Mac升级了OSX 10.11后,配置class-dump的时候,会发现逆向书上推荐的class-dump存放目录/usr/bin,class-dump存放不进去,尝试过用sudo 还是不被允许 ...

  3. Android的 EditText的inputType类型

    android开发过程中突然发现的warning EditText 报出 “This text field does not specify an inputType or a hint”   原因: ...

  4. android 蓝牙编程重点---如何发送和接收16进制数据

    最近的android蓝牙开发项目也逐渐接近尾声,基本的功能都已经完成,只剩下界面的设计.现在真的是舒了一口气! 作为编程学习经验只有1年的菜鸟,这是我独自完成的商业性产品,而且还是涉及到与单片机蓝牙模 ...

  5. Linux增加swap空间

    1.添加交换文件并设置其大小为12G,使用如下命令 # dd if=/dev/zero of=/home/swapfile bs=1024 count=12288000 12288000+0 reco ...

  6. C/C++返回内部静态成员的陷阱

    在我们用C/C++开发的过程中,总是有一个问题会给我们带来苦恼.这个问题就是函数内和函数外代码需要通过一块内存来交互(比如,函数返回字符串),这个问题困扰和很多开发人员.如果你的内存是在函数内栈上分配 ...

  7. CoreImage 中的模糊滤镜

    1.CoreImage 中的模糊滤镜 1.1CoreImage是苹果用来简化图片处理的框架 1.2CIImage.CIFilter与CIContext三者联系 1.3CIGaussianBlur中可能 ...

  8. [转]Spring注解-@Configuration注解、@Bean注解以及配置自动扫描、bean作用域

    1.@Configuration标注在类上,相当于把该类作为spring的xml配置文件中的<beans>,作用为:配置spring容器(应用上下文) package com.test.s ...

  9. uiautomatorviewer 查看元素新思路

    用adb 命令把图片和uix获取出来,再导入uiautomatorviewer adb shell uiautomator dump /data/local/tmp/uidump.uixadb pul ...

  10. kafka 监控(eagle)

    topic:创建时topic名称 partition:分区编号 offset:表示该parition已经消费了多少条message logSize:表示该partition已经写了多少条message ...