AsyncTask

来源:互联网 发布:淘宝高端礼物 编辑:程序博客网 时间:2024/05/01 14:57
自android1.5之后,引进了android.os.AsyncTask,使用AsyncTask能够简单的处理一些需要与界面交互的长时间任务。

AsyncTask<Params, Progress, Result>有以下几个回调方法:

doInBackground()       这个方法会在用户工作线程中执行
onCancelled()             取消时调用的方法
onPostExecute()         在doInBackground()运行完成后调用,用于运行结果反馈
onPreExecute()           在doInBackground()前调用,通常用于创建需要的数据
onProgressUpdate()    更新进度,只要在任务中调用publishProgress(),此方法就会被回调

onPostExecute()、onPreExecute()、onProgressUpdate()都是在主线程中运行的,所以可以对View进行操作,免去了使用handler繁琐的步骤。

AsyncTask<Params, Progress, Result>中的三个参数:
第一个参数是doInBackground()接收的参数,第二个参数为onProgressUpdate()接收参数,第三个参数为onPostExecute()接收参数,可以根据需要设定相应类型。


示例代码:
package com.lxb.asynctask;import android.app.Activity;import android.os.AsyncTask;import android.os.Bundle;import android.util.Log;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.ProgressBar;import android.widget.TextView;public class AsyncTaskTestActivity extends Activity implements OnClickListener {private final String TAG = "AsyncTaskTestActivity";private Button btn_run;private Button btn_cancle;private ProgressBar progressBar;private TextView tv_info;private AsyncTask<String, Integer, String> task;    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);                findViews();    }        private void findViews() {    btn_run = (Button) findViewById(R.id.btn_run);    btn_cancle = (Button) findViewById(R.id.btn_cancle);    progressBar = (ProgressBar) findViewById(R.id.progressBar);    tv_info = (TextView) findViewById(R.id.tv_info);        progressBar.setMax(100);    progressBar.setProgress(0);    btn_run.setOnClickListener(this);    btn_cancle.setOnClickListener(this);    }@Overridepublic void onClick(View v) {switch(v.getId()) {case R.id.btn_run:task = new AsyncTask<String, Integer, String>() {int progress;int max;@Overrideprotected String doInBackground(String... params) {Log.i(TAG, "doInBackground()");Log.i(TAG, "task: " + params[0] + " is running!");while(progress < max) {Log.i(TAG, "running");progress++;publishProgress(progress, progress + 4);try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}return "load finished!";}@Overrideprotected void onCancelled() {super.onCancelled();Log.i(TAG, "onCancelled()");}@Overrideprotected void onPostExecute(String result) {super.onPostExecute(result);Log.i(TAG, "onPostExecute()");tv_info.setText(result);}@Overrideprotected void onPreExecute() {super.onPreExecute();Log.i(TAG, "onPreExecute()");progress = 0;max = 100;progressBar.setMax(max);    progressBar.setProgress(progress);}@Overrideprotected void onProgressUpdate(Integer... values) {super.onProgressUpdate(values);progressBar.setProgress(values[0]);progressBar.setSecondaryProgress(values[1]);tv_info.setText(values[0] + "%");}};task.execute("my task");break;case R.id.btn_cancle:if(task != null) {task.cancel(true);}break;}}    }

源码下载:http://download.csdn.net/detail/shinay/4512695


补充:
AsyncTask内部是有一个线程池来管理的,而这个线程池中限定了只能有5个任务同时进行,因此,我们如果在使用AsyncTask多于5个,那么多余的任务就会处于等待状态,等前面的任务执行完,才会开始执行。
这样的话,对于有大量任务的使用情景,可能就有点不太合适。但是,在3.0版本后,google也是提供了executeOnExecutor()这样的接口,可以自定义线程池来解决这一问题,具体的介绍可以参考以下这篇文章:
http://blog.csdn.net/hitlion2008/article/details/7983449