定义
AsyncTask 是Android提供的一个轻量级的异步类,在类中实现异步操作,并提供接口反馈当前执行异步进度,最后执行结果反馈给UI主线程
它比Handler更轻量级,适合做一些比较简单的操作,它结构清晰,功能定义明确
在这里随便提一下Android当中的UI主线程和子线程
通过情况下,在一个android应用程序启动的时候,会单独启动一个进程Process,android中的四大组件都会运行在这个进程当中,这个进程中包括很多个的子线程
在这么多的子线程当中,包含一个叫UI 主线程,即UI MainThread,它在程序运行的时候就创建,主要负责界面的显示,更新和控件交互,在Android程序创建之初,一个Process呈现的是单线程模型,所有的任务都在一个线程中运行。因此,我们认为,UIThread所执行的每一个函数,所花费的时间都应该是越短越好。而其他比较费时的工作(访问网络,下载数据,查询数据库等),都应该交由子线程去执行,以免阻塞主线程。
所以在UI主线程中去执行一些访问网络或者下载数据就会抛出异常。
由于主线程(也可叫UI线程)负责处理用户输入事件(点击按钮、触摸屏幕、按键等),如果主线程被阻塞,应用就会报ANR错误。为了不阻塞主线程,我们需要在子线程中处理耗时的操作,在处理耗时操作的过程中,子线程可能需要更新UI控件的显示,由于UI控件的更新重绘是由主线程负责的,所以子线程需要通过Handler发送消息到主线程的消息队列中,由运行在主线程的消息处理代码接收到消息后才能更新UI控件的显示。
采用线程+Handler实现异步处理时,当每次执行耗时操作都创建一条新线程进行处理,性能开销会比较大。另外,如果耗时操作执行的时间比较长,就有可能同时运行着许多线程,系统将不堪重负。为了提高性能,我们可以使用AsyncTask实现异步处理,事实上其内部也是采用线程+Handler来实现异步处理的,只不过是其内部使用了线程池技术,有效地降低了线程创建数量及限定了同时运行的线程数。
AsyncTask三个泛型参数:
第一个Params 指定了doInBackground()方法输入参数的类型
第二个 Progress 指定了onProgressUpdate()方法输入参数的类型
第三个 Result 指定了onPostExecute()方法输入参数的类型和doInBackground()方法返回值的类型
onPreExecute(): 该方法在UI线程运行,当AsyncTask的execute()方法执行后,onPreExecute()会首先执行。可以在该方法中做一些准备工作,如初始化进度条的最大值。
doInBackground(Params...): 将在onPreExecute()方法执行后马上执行,该方法运行在子线程中,负责执行耗时操作。在执行耗时操作的过程中你可以不断地调用publishProgress()方法,导致onProgressUpdate()不断地被调用。
onProgressUpdate(Progress...),调用publishProgress()方法,就会导致该方法被执行,该方法运行在UI线程,例如在该方法中你可以更新进度条的显示。
onPostExecute(Result):doInBackground()方法执行后的返回结果会传给该方法,该方法运行在UI线程,在该方法中你可以显示处理结果。
使用AsyncTask类,以下是几条必须遵守的准则:
- Task的实例必须在UI thread中创建;
- execute方法必须在UI thread中调用;
- 不要手动的调用onPreExecute(), onPostExecute(Result),doInBackground(Params...), onProgressUpdate(Progress...)这几个方法;
- 该task只能被执行一次,否则多次调用时将会出现异常;
package com.android.asyncTask;
import android.os.AsyncTask;
import android.widget.ProgressBar;
import android.widget.TextView;
/**
* 异步更新进度条
*@author yangjp
*@version V1.0
*/
public class UpdateTask extends AsyncTask<String, Integer, String> {
private TextView textView = null;
private ProgressBar progressBar = null;
public UpdateTask(TextView textView,ProgressBar progressBar){
this.textView = textView;
this.progressBar = progressBar;
}
/*(non Javadoc)
*<p>Title: onPreExecute</p>
*<p>Description: </p>
*@see android.os.AsyncTask#onPreExecute()
*/
@Override
protected void onPreExecute() {
super.onPreExecute();
progressBar.setMax(100);
textView.setText("开始执行异步线程");
}
/*(non Javadoc)
*<p>Title: doInBackground</p>
*<p>Description: </p>
*@param params
*@return
*@see android.os.AsyncTask#doInBackground(Params[])
*/
@Override
protected String doInBackground(String... params) {
String param = params[0];
int index = 0;
if(param !=null){
for(int i =1;i <= 100;i++){
index = i;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
publishProgress(i);
}
}
return param + " :当前进度:" + index;
}
/*(non Javadoc)
*<p>Title: onPostExecute</p>
*<p>Description: </p>
*@param result
*@see android.os.AsyncTask#onPostExecute(java.lang.Object)
*/
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
textView.setText("异步操作执行结束:" + result);
}
/*(non Javadoc)
*<p>Title: onProgressUpdate</p>
*<p>Description: </p>
*@param values
*@see android.os.AsyncTask#onProgressUpdate(Progress[])
*/
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
int vlaue = values[0];
progressBar.setProgress(vlaue);
textView.setText("当前进度: " + vlaue );
}
}
/**
* Copyright (C) 2012 HongCheng System Inc.
*/
package com.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;
/**
* 更新主界面
*
* @author yangjp
* @version V1.0
*/
public class UpdateActivity extends Activity {
// 按钮
private Button button = null;
// 进度条
private ProgressBar progressBar = null;
//文本
private TextView textView = null;
/*
* (non Javadoc)<p>Title: onCreate</p><p>Description: </p>
*
* @param savedInstanceState
*
* @see android.app.Activity#onCreate(android.os.Bundle)
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.update_task);
textView = (TextView)findViewById(R.id.textView01);
progressBar = (ProgressBar)findViewById(R.id.progressBar02);
button = (Button)findViewById(R.id.button03);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
UpdateTask updateTask = new UpdateTask(textView, progressBar);
updateTask.execute("测试");
}
});
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/textView01"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<ProgressBar
android:id="@+id/progressBar02"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/button03"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="更新progressbar" />
</LinearLayout>