转载请表明出处:http://blog.csdn.net/u012637501(嵌入式_小J的天空)
一、引言
    我们知道Android的UI线程主要负责处理用户的按键事件、用户触屏事件及屏幕画图事件等,对于其它的操作尽量不要在UI线程中实现,由于这些操作非常有可能会堵塞UI线程,比方一些耗时操作,会导致UI界面停止响应,从而减少了用户的体验。所以,为了避免UI线程失去响应的问题,Android建议将耗时操作放在新线程中完毕。但新线程也可能须要动态更新UI组件:比方须要从网上获取一个网页,然后在TextView中将其源码显示出来,此时就应该将连接网络,获取网络数据的操作(耗时)放在新线程中完毕。
    可是。问题来了:当获取网络数据之后。因为新线程不同意直接更新UI组件,我们该怎样更新UI组件数据呢?为了解决新线程不能更新UI组件问题。Android提供了例如以下几种解决方式:
(1)使用Handler消息传递机制实现线程之间的通信(如上一篇文章所述);
(2)Activity.runOnUiThread(Runnable);
(3)View.post(Runnable);
(4)View.postDelayed(Runnable long);
(5)异步任务。又因为(2)~(4)方式有可能导致编程有点繁琐。而异步任务则可简化这样的操作。
二、AsyncTask简单介绍
    Android的类AsyncTask对线程间通讯进行了包装,提供了简易的编程方式使后台线程和UI线程进行通讯:后台线程运行异步任务。并把操作结果通知UI。不再须要子线程和Handler就能够完毕异步操作而且刷新用户界面。
1.AsyncTask类
    AsyncTask<>是一个抽象类。通经常使用于被继承,继承AsyncTask时须要指定例如以下三种泛型參数:
(1)Params:启动任务运行输入參数的类型;
(2)Progress:后台任务完毕的进度值(百分比)的类型;
(3)Result:后台运行任务完毕后返回结果的类型,如String、Integer;
2.Async类中主要方法
(1)onPreExecute():该方法将在运行实际的后台操作前被UI线程调用。

能够在该方法中做一些准备工作,如在界面上显示一个进度条,或者一些控件的实例化,这种方法能够不用实现。

-----(UI线程调用,后台线程未启动,初始化工作)
(2)doInBackground(Params...values):将在onPreExecute
方法运行后立即运行,该方法运行在后台线程中。这里将主要负责运行那些比較耗时的后台处理工作。能够调用 publishProgress()方法来实时更新任务进度。该方法是抽象方法,子类必须实现。
-----(后台线程调用。运行后台任务)
(3)onProgressUpdate(Progress...values):在publishProgress方法被调用后,UI
线程将调用这种方法从而在界面上展示任务的进展情况,比如通过一个进度条进行展示。
-----(UI线程调用。展现后台任务进展)
(4)onPostExecute(Result):在doInBackground
运行完毕后。onPostExecute 方法将被UI线程调用,后台的计算结果(doInBackground方法返回值)将通过该方法传递到UI线程,而且在界面上展示给用户。

-----(UI线程调用。显示后台线程执行结果)
(5) onCancelled():在用户取消线程操作的时候调用。在主线程中调用onCancelled()的时候调用。
-----(UI线程调用,取消后台线程) 
三、异步任务处理开发步骤
1.创建AsyncTask的子类,并为三个泛型參数指定类型。假设某个泛型參数不须要指定类型,则将它指定为Void。
2.依据须要实现AsyncTask上述五中方法;
3.调用AsyncTask子类的实例的execute(Params... params)開始运行耗时任务。

另外,使用AsyncTask类须要遵守的下面准则:
(1)Task的实例必须在UI线程中创建;
(2)execute(Params...)方法必须在UI线程中调用;
(3)不要手动的调用onPreExecute(),
onPostExecute(Result),doInBackground(Params...),onProgressUpdate(Progress...)这几个方法。须要在UI线程中实例化这个task来调用;
(4)该task仅仅能被运行一次。否者多次调用时将会出现异常。
四、源代码实战
1.实现功能

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMjYzNzUwMQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" width="474" height="365" alt="" style="background-color:inherit; display:inline-block; margin-top:8px; width:473.75846501128666px; height:365px">

2.源代码实现
(1)MainActivity.java
功能:用以获取界面组件。实例化一个AsyncTask子类对象并调用其exeute(Integer....params)方法以指定參数params执行一个任务。
package com.example.android_asynctask;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
public class MainActivity extends Activity {
private Button downbtn;
private TextView textView;
private ProgressBar progressBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
downbtn = (Button)findViewById(R.id.download);
textView = (TextView)findViewById(R.id.text);
progressBar = (ProgressBar)findViewById(R.id.progressBar);
final DownloadTest download = new DownloadTest(textView,progressBar); //获取一个DownloadTest对象。并传递组件对象參数
downbtn.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v) {
download.execute(200);
}
}); }
}
(2)DownloadTest.java
功能:继承于AsyncTask的子类。当中onPreExecute()作用是为执行后台线程(子线程)完毕初始化工作;doInBackground方法执行后台线程;onProgressUpdate方法更新UI;onPostExecute方法处理后台线程执行结果。
package com.example.android_asynctask;
import android.graphics.Color;
import android.os.AsyncTask;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;
public class DownloadTest extends AsyncTask<Integer,Integer,String>
{
private TextView tv;
private ProgressBar pb;
//带參数构造方法
DownloadTest(TextView text,ProgressBar bar)
{
this.tv = text;
this.pb = bar;
}
//不带參数构造方法
DownloadTest()
{
}
/*1.onPreExecute方法
* 为子线程(后台)执行初始化相关内容
*/
protected void onPreExecute() {
tv.setVisibility(View.VISIBLE); //设置显示文本组件
pb.setVisibility(View.VISIBLE); //设置显示运行进度条
super.onPreExecute();
}
/*2.doInBackground方法
* 执行一个后台线程,该线程实现每arg0[0]毫秒调用一次onProgressUpdate方法
*/
protected String doInBackground(Integer... arg0) {
for(int i=0;i<100;i++)
{
publishProgress(i); //调用onProgressUpdate方法并传递參数i
try {
Thread.sleep(arg0[0]); //累加一次,线程休眠argo[0]毫秒
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return "完成下载"; //后台子线程执行完成后。返回的值
}
/*3.onProgressUpdate方法
* 调用publishProgress(i)时调用该方法,并传递參数i给形參values[0]*/ @Override
protected void onProgressUpdate(Integer... values) {
pb.setProgress(values[0]); //设置进度条值
tv.setText("已经下载"+values[0]+"%"); //文本组件显示提示信息
super.onProgressUpdate(values);
}
/*4.onPostExecute
* 处理后台线程得到的结果
* */
protected void onPostExecute(String result) {
pb.setVisibility(View.INVISIBLE); //隐藏进度条
tv.setVisibility(View.VISIBLE); //显示UI文本显示框组件
tv.setText(result);
tv.setTextSize(20);
tv.setTextColor(Color.RED);
super.onPostExecute(result);
}
}

效果演示:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMjYzNzUwMQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">


源代码分析:
    通过源代码我们能够知道。主线程通过调用AsyncTask子类的execute()方法,进而调用AsyncTask子类的onPreExecute方法,用以再执行后台线程之前为其初始化相关内容。

然后,在新创建的子线程中调用doInBackground()方法实现后台线程功能并通过publishProgress()方法调用onProgressUpdate()方法更新UI内容,最后在主线中执行onPostExecute方法来处理后台线程执行的结果。

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMjYzNzUwMQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" width="386" height="250" alt="" style="background-color:inherit; display:inline-block; margin-top:8px; width:385.8520900321543px; height:250px">

注意:当中仅仅有doInBackground()方法,以及publishProgress()方法是在子线程中运行的。其它的方法都是在主线程中运行的。所以能够在这些方法中更新界面组件。

版权声明:本文博客原创文章,博客,未经同意,不得转载。

Android备注26.Android异步任务(AsyncTask)的更多相关文章

  1. Android多线程分析之五:使用AsyncTask异步下载图像

    Android多线程分析之五:使用AsyncTask异步下载图像 罗朝辉 (http://www.cnblogs.com/kesalin) CC 许可,转载请注明出处 在本系列文章的第一篇<An ...

  2. Java基础知识强化之网络编程笔记15:Android网络通信之 Android异步任务处理(AsyncTask使用)

         AsyncTask,是android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作,并提供接口反馈当前异步执行的程度(可以通过接口实现UI进度更新),最后反馈执行的 ...

  3. Android 之异步任务(AsyncTask,Handler,Message,looper)

    AsyncTask: 3个类型(Params,Progress和Result),4个步骤(onPreExecute(),doInBackground(Params…),onProgressUpdate ...

  4. Android中使用Thread线程与AsyncTask异步任务的区别

    最近和几个朋友交流Android开发中的网络下载问题时,谈到了用Thread开启下载线程时会产生的Bug,其实直接用子线程开启下载任务的确是很Low的做法,那么原因究竟如何,而比较高大上的做法是怎样? ...

  5. android:异步任务asyncTask介绍及异步任务下载图片(带进度条)

    为什么要用异步任务? 在android中仅仅有在主线程才干对ui进行更新操作.而其他线程不能直接对ui进行操作 android本身是一个多线程的操作系统,我们不能把全部的操作都放在主线程中操作 .比方 ...

  6. Android异步载入AsyncTask具体解释

    曾看见有人说过.认为非常有道理.分享一下:   技术分为术和道两种:   (1)具体做事的方法是术.   (2)做事的原理和原则是道. 近期项目发现个重大问题.结果打log跟踪查是AsyncTask导 ...

  7. Android 旋转屏幕--处理Activity与AsyncTask的最佳解决方案

    一.概述 运行时变更就是设备在运行时发生变化(例如屏幕旋转.键盘可用性及语言).发生这些变化,Android会重启Activity,这时就需要保存activity的状态及与activity相关的任务, ...

  8. Android实战技巧:深入解析AsyncTask

    AsyncTask的介绍及基本使用方法 关于AsyncTask的介绍和基本使用方法可以参考官方文档和Android实战技巧:多线程AsyncTask这里就不重复. AsyncTask引发的一个问题 上 ...

  9. Android异常一、异步任务导致的窗口句柄泄漏问题(转)

    05-05 10:36:41.009: E/WindowManager(4243): Activity com.tao.MyActivity has leaked window com.android ...

随机推荐

  1. jquery画图插件jPainter

    jquery画图插件jPainter 一.总结 一句话总结:四年前的项目,四年无更新,不好用. 二.基于HTML5 Canvas和jQuery 的画图工具的实现 简介 HTML5 提供了强大的Canv ...

  2. php实现求对称二叉树(先写思路,谋而后动)

    php实现求对称二叉树(先写思路,谋而后动) 一.总结 1.先写思路,谋而后动 二.php实现求对称二叉树 题目描述: 请实现一个函数,用来判断一颗二叉树是不是对称的.注意,如果一个二叉树同此二叉树的 ...

  3. 【u007】血色先锋队

    Time Limit: 1 second Memory Limit: 128 MB [问题描述] 巫妖王的天灾军团终于卷土重来,血色十字军组织了一支先锋军前往诺森德大陆对抗天灾军团,以及一切沾有亡灵气 ...

  4. [tmux] Manage terminal workspaces using session naming

    It's a lot easier to manage your tmux session when they have sensible names. We'll cover: How to cre ...

  5. sublime-1 sublime设置到鼠标右键

    sublime-1 sublime设置到鼠标右键 一.总结 一句话总结:其实windows可以更加熟悉一点才好,毕竟用的那么多,regedit可以添加注册,也可以添加鼠标右键选项. 二.sublime ...

  6. 【????】最短路(short)

    问题描述: 给出N个点,M条无向边的简单图,问所有点对之间的最短路. 数据输入: 第1行两个正整数N,M(N<=100,M<=5000) 下面M行,每行3个正整数x, y, w,为一条连接 ...

  7. 【poj3468】A Simple Problem with Integers

    Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 97008   Accepted: 30285 Case Time Limi ...

  8. 解决离线Could not parse configuration:hibernate.cfg.xml错误

    离线使用hibernate tool 生成反向工程,在配置 配置文件完,生成配置文件后,会报出org.hibernate.HibernateException: Could not parse con ...

  9. Oracle数据库sqlplus与plsqldev解决乱码

    (出现乱码 解决方法留存) 问题描述 : 在用eclipse使用jdbc插入中文数据的时,数据用plsqldev查询时,正常显示中文,但是用sqlplus查询时,为中文乱码,当用plsqldev直接插 ...

  10. window.load和ready的差别

    1.运行时机: window.onload:必须等待网页所有加在完成(包含图片等),然后再运行包裹代码 $(document).ready():仅仅须要等待网页中的DOM结构载入完成.就能运行包裹的代 ...