1.AsyncTask类为耗时的操作移到后台线程并在操作完成后同步更新UI线程提供了最佳实践模式。它有助于将事件处理程序与GUI线程进行同步,允许更新视图和其他UI元素来报告进度,或者在任务完成后发布结果。
a.创建新的异步任务
//异步任务 三个参数:输入 进度报告 结果值的参数类型
new AsyncTask<String, Integer, String>() {
/**
* 首先会调用的方法
*/
@Override
protected void onPreExecute() {
mProgressDialog.setTitle("泥煤");
mProgressDialog.setMessage("正在努力加载中...");
mProgressDialog.setCancelable(false);
mProgressDialog.setMax(str.length());
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.show();
}
/**
* doInBackground完成后,其返回值传入到这个事件处理程序
* 运行在主线程,可以安全修改UI元素
*/
@Override
protected void onPostExecute(String result) {
mProgressDialog.dismiss();
tv_text.setText(result);
}
/**
* 中间进度更新变化时作更新UI操作
* 运行在主线程,可以安全修改UI元素
*/
@Override
protected void onProgressUpdate(Integer... values) {
mProgressDialog.setProgress(values[0]);
}
/**
* 此方法在后台线程执行,运行比较耗时的操作,比如文件IO 网络下载之类
* 可以调用publicProgress方法以传递参数值给onProgressUpdate处理程序
* 后台任务执行完成,将最终结果作为参数传递给onPostExecute处理程序
*/
@Override
protected String doInBackground(String... params) {
String result = "";
int myProgress = 0;
int max = params[0].length();
for(int i=1;i<=max;i++){
myProgress = i;
result = result + params[0].charAt(max-i);
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
publishProgress(myProgress);
}
return result;
}
};
b.执行异步任务
当实现了异步任务后,可以通过创建新示例并调用execute来执行他/她。
String str = "";
new MyAsyncTask().execute(str);
c.完整代码
package com.example.asynctask;
import android.app.Activity;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.TextView;
public class MainActivity extends Activity {
private ProgressDialog mProgressDialog;
private TextView tv_text;
String str = "The application may be doing too much work on its main thread.";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mProgressDialog = new ProgressDialog(this);
tv_text = (TextView) findViewById(R.id.tv_text);
startQuery();
}
private void startQuery() {
//异步任务 三个参数:输入 进度报告 结果值的参数类型
new AsyncTask<String, Integer, String>() {
/**
* 首先会调用的方法
*/
@Override
protected void onPreExecute() {
mProgressDialog.setTitle("泥煤");
mProgressDialog.setMessage("正在努力加载中...");
mProgressDialog.setCancelable(false);
mProgressDialog.setMax(str.length());
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.show();
}
/**
* doInBackground完成后,其返回值传入到这个事件处理程序
* 运行在主线程,可以安全修改UI元素
*/
@Override
protected void onPostExecute(String result) {
mProgressDialog.dismiss();
tv_text.setText(result);
}
/**
* 中间进度更新变化时作更新UI操作
* 运行在主线程,可以安全修改UI元素
*/
@Override
protected void onProgressUpdate(Integer... values) {
mProgressDialog.setProgress(values[0]);
}
/**
* 此方法在后台线程执行,运行比较耗时的操作,比如文件IO 网络下载之类
* 可以调用publicProgress方法以传递参数值给onProgressUpdate处理程序
* 后台任务执行完成,将最终结果作为参数传递给onPostExecute处理程序
*/
@Override
protected String doInBackground(String... params) {
String result = "";
int myProgress = 0;
int max = params[0].length();
for(int i=1;i<=max;i++){
myProgress = i;
result = result + params[0].charAt(max-i);
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
publishProgress(myProgress);
}
return result;
}
}.execute(str);
}
}
2.每个AsyncTask实例只能执行一次,如果二次调用的话则会抛出异常。
AsyncTask对于生命周期较短且需要在UI上显示进度和结果的后台操作是很好的解决方案。然而,当Activity重新启动时,这种操作将不会持续进行,也就是说当设备的方向变化导致Activity被销毁和重新创建时,AsyncTask会被取消。对于生命周期较长的后台操作,如从网上下载数据,使用service仍是最好的选择。