使用Android提供的AsyncTask类可以将耗时的操作放在后台进行处理,同时对主线程进行UI更新以显示任务执行的进度情况。AsyncTask处理线程创建、管理和同步全部工作,用它来创建的异步任务主要由两部分组成:在后台执行耗时任务,以及在处理完成后执行UI更新。需要注意的是,AsyncTask在Activity重新启动以后,异步任务不会持续执行,也就是说AsyncTask在设备的方向发生变化而导致Activity被销毁或重新创建时会被取消。所以,生命周期较长的后台操作不宜使用AsyncTask,可以使用Service来实现。
创建并使用异步任务AsyncTask:
示例通过异步任务来更新进度条,并在任务结束后进行提示,如下面的界面所示:
界面组件及布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="10dip" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/async_task_title"
android:textSize="16sp" />
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dip"
android:layout_marginBottom="10dip" >
<TextView
android:id="@+id/process_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_marginBottom="5dip"
android:text="0%"
android:textSize="15sp"
/>
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="fill_parent"
android:layout_height="6dip"
android:layout_below="@id/process_text"
android:max="100"
android:progressDrawable="@drawable/process_bg" />
</RelativeLayout>
<Button
android:id="@+id/start_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/async_start_btn" />
<TextView
android:id="@+id/result_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#22CB22"
android:layout_marginTop="10dip"
android:padding="15dip"
android:textSize="20sp"
android:textStyle="bold"
android:textColor="#fff"
android:visibility="gone" />
</LinearLayout>
异步任务实现类:
package cn.qing.android.task;
import android.os.AsyncTask;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;
public class ProcessTask extends AsyncTask<Void, Integer, String> {
private ProgressBar bar;
private TextView resultText,processText;
public ProcessTask(ProgressBar bar,TextView processText,TextView resultText)
{
this.bar = bar;
this.processText = processText;
this.resultText = resultText;
}
@Override
protected String doInBackground(Void... param) {
int max = bar.getMax();
for (int i = 1; i <= max; i++) {
publishProgress(i);
//间隔1s后再更新进度
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return "异步任务执行完成...";
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
// 异步任务执行完成以后,更新界面提示异步任务执行完成
resultText.setText(result);
resultText.setVisibility(View.VISIBLE);
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
// 更新进度条
bar.setProgress(values[0]);
//更新进度数字显示
processText.setText(""+values[0]+"%");
}
}
异步任务对应的Activity类:
package cn.qing.android;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import cn.qing.android.task.ProcessTask;
public class AsyncTaskActivity extends Activity {
private static final String TAG = "AsyncTaskActivity";
private Button startButton;
private ProgressBar bar;
private TextView processText,resultText;
private static final String KEY_PROCESS_VALUE = "processTextKey";
private static final String KEY_RESULT_VALUE = "resultTextKey";
private static final String KEY_RESULT_ISSHOE = "resultIsShowKey";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.async_task_layout);
bar = (ProgressBar)findViewById(R.id.progressBar);
processText = (TextView)findViewById(R.id.process_text);
resultText = (TextView)findViewById(R.id.result_text);
startButton = (Button)findViewById(R.id.start_btn);
startButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new ProcessTask(bar,processText,resultText).execute();
}
});
Log.i(TAG, "onCreate.............");
}
@Override
protected void onSaveInstanceState(Bundle outState) {
Log.i(TAG, "onSaveInstanceState............");
outState.putString(KEY_PROCESS_VALUE, processText.getText().toString());
outState.putString(KEY_RESULT_VALUE, resultText.getText().toString());
outState.putInt(KEY_RESULT_ISSHOE, resultText.getVisibility());
super.onSaveInstanceState(outState);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
if(null != savedInstanceState)
{
processText.setText(savedInstanceState.getString(KEY_PROCESS_VALUE));
resultText.setVisibility(savedInstanceState.getInt(KEY_RESULT_ISSHOE));
resultText.setText(savedInstanceState.getString(KEY_RESULT_VALUE));
Log.i(TAG, "数据已恢复.......");
}
Log.i(TAG, "onRestoreInstanceState............");
}
@Override
protected void onPause() {
super.onPause();
Log.i(TAG, "Activity pause............");
}
@Override
protected void onResume() {
super.onResume();
Log.i(TAG, "Activity resume............");
}
}
类ProcessTask继承了AsyncTask类,在AsyncTask类的定义及使用时需要指定使用的参数类型,在上面的实现中使用的是AsyncTask<Void, Integer, String> 第一个类型定义为Void来指明 AsyncTask不接受任何类型的入参,这个参数的类型定义将决定protected String doInBackground(Void... param) 方法的参数类型,第二个参数是进度参数的类型,它的类型决定这方法protected void onProgressUpdate(Integer... values) 的参数类型,这个方法是当在执行任务调用publishProgress();时,对进度进行更新,第三个参数是返回的结果类型,分别对应doInBackground方法的返回类型,以及方法protected void onPostExecute(String result)的入参类型。
在实现AsyncTask类时,必须实现doInBackground()方法,下面对AsyncTask中使用到的那几个方法做简要说明:
1、protected String doInBackground(Void... param)
这个方法主要是用来执行异步任务中的具体任务,它的参数类型在继承AsyncTask时就已经指定,如果不需要任何参数,可以将类型指定为Void类型,异步任务执行完成以后如果需要返回结果,可以在集成AsyncTask类时指定返回结果类型,这样就可以在下面的onPostExecute()方法是接收这个结果。
2、protected void onPostExecute(String result)
这个方法就是接受上面doInBackground()方法的返回结果的,一般在执行完异步任务后,需要在前台界面上更新UI来进行提示,这个时候就可以在此做处理。
3、publishProgress()
这个方法是用传递值给onProgressUpdate()方法,进行进度UI更新的
4、onProgressUpdate()
接受进度值的变化,更新UI显示
使用定义的ProcessTask类:
在AsyncTaskActivity中当开始任务的按钮点击事件触发时,就实例化自定义的ProcessTask类,并在构造方法中传递ProgressBar以及TextView控件,使其在ProcessTask类中使用他们对UI进行更新。当任务执行时进度条开始加载,进度显示文本也开始更新其值,更新至100%时,任务结束,下面显示出异步任务执行完成的提示。
在AsyncTaskActivity中,使用了Activity的状态保存及恢复方法:onSaveInstanceState和onRestoreInstanceState,之所以使用他们来存储界面UI控件的值,是因为当AsyncTaskActivity被至于后台不显示时,如果出现系统内存不足的情况,Android会将这个Activity进入Pause状态,会调用Pause方法,如果在onSaveInstanceState方法中对当前的控件的值进行保存,再次加载时界面的控件值就会恢复到最开始的状态,所以在这个Activity中实现了onSaveInstanceState和onRestoreInstanceState以存储和恢复界面UI的值。