AsyncTask 是Android中比较流行的几个类中的一个,因为它很容易使用。它允许开发者定义一个运行在单独线程中的任务,还能在任务的不同阶段提供回调函数。这些回调函数被设计成无需使用 runOnUiThread 方法即可更新UI,这非常适合表示长时间运行的操作的进度。下面的示例使用 AsyncTask 来完成 Thread 例子中的功能:
public class MyAsyncTask extends AsyncTask<String, Integer, Integer> {
private Activity mActivity;
public MyAsyncTask(Activity activity) {
mActivity = activity;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
// 下面的代码会运行在主线程中
mActivity.findViewById(R.id.progressBar).
setVisibility(View.VISIBLE);
((ProgressBar) mActivity.findViewById(R.id.progressBar)).
setProgress(0);
}
@Override
protected Integer doInBackground(String... inputs) {
// 下面的代码不会运行在主线程中
int progress = 0;
for (String input : inputs) {
// 把输入上传到服务器(用睡眠代替)
SystemClock.sleep(50);
publishProgress(++progress, inputs.length);
}
return progress;
}
@Override
protected void onProgressUpdate(Integer... values) {
// 下面的代码会运行在主线程中
((ProgressBar) mActivity.findViewById(R.id.progressBar)).
setMax(values[1]);
((ProgressBar) mActivity.findViewById(R.id.progressBar)).
setProgress(values[0]);
}
@Override
protected void onPostExecute(Integer i) {
super.onPostExecute(i);
// 下面的代码会运行在主线程中
mActivity.findViewById(R.id.progressBar).
setVisibility(View.INVISIBLE);
}
}
上面的例子实现了四个回调函数,并在代码注释中表明了它们会运行在哪个线程。可以看到,onPreExecute 、 onProgressUpdate 和 onPostExecute 方法都运行在主线程,所以可以安全地在这些线程中更新UI。每次触发 onProgressUpdate 回调函数都会调用 publishProgress ,这样可以更新进度条。通过 AsyncTask 类,开发者可以很容易在其他线程中执行耗时的任务,也可以在需要时很方便地和主线程通信。使用 AsyncTask 唯一的问题是该类的实例只能使用一次,这意味着每次执行操 作 都 要 新 建 一 个 MyAsyncTask 对 象 。 虽 然 是 个 轻 量 级 的 类 ( 实 际 的 线 程 是 由ExecutorService 管理的),但它不适合那些频繁的操作,因为这会快速聚集需要垃圾回收的对象,并最终导致应用程序界面卡顿。
此外, AsyncTask 不能对操作设置执行时间,也无法间隔一段时间执行操作。它适合文件下
载,以及不会频繁发生或通过用户交互等类似情况的操作。