为了解决这一问题,OPhone在1.5版本引入了AsyncTask。AsyncTask的特点是任务在主线程之外运行,而回调方法是在主线程中执行,这就有效地避免了使用Handler带来 的麻烦。阅读AsyncTask的源码可知,AsyncTask是使用java.util.concurrent框架来管理线程以及任务的执行的,concurrent框架是一个非常成熟,高效的框架,经过了严格的测试。这说明AsyncTask的设计很好的解决了匿名线程存在的问题。
AsyncTask是抽象类,子类必须实现抽象方法doInBackground(Params... p),在此方法中实现任务的执行工作,比如连接网络获取数据等。通常还应该实现onPostExecute(Resultr)方法,因为应用程序关心的结果在此方法中返回。需要注意的是AsyncTask一定要在主线程中创建实例。AsyncTask定义了三种泛型类型Params,Progress和Result。
* Params启动任务执行的输入参数,比如HTTP请求的URL。
* Progress后台任务执行的百分比。
* Result后台执行任务最终返回的结果,比如String。
AsyncTask的执行分为四个步骤,与前面定义的TaskListener类似。每一步都对应一个回调方法,需要注意的是这些方法不应该由应用程序调用,开发者需要做的就是实现这些方法。在任务的执行过程中,这些方法被自动调用。
* onPreExecute()当任务执行之前开始调用此方法,可以在这里显示进度对话框。
* doInBackground(Params...)此方法在后台线程执行,完成任务的主要工作,通常需要较长的时间。在执行过程中可以调用publicProgress(Progress...)来更新任务的进度。
*onProgressUpdate(Progress...)此方法在主线程执行,用于显示任务执行的进度。
* onPostExecute(Result)此方法在主线程执行,任务执行的结果作为此方法的参数返回。
三个泛型参数:
Param 任务执行器需要的数据类型
Progress 后台计算中使用的进度单位数据类型
Result 后台计算返回结果的数据类型
有些参数是可以设置为不使用的,只要传递为Void型即可,比如AsyncTask</VOID,>
四个步骤:
onPreExecute(),执行预处理,它运行于UI线程,可以为后台任务做一些准备工作,比如绘制一个进度条控件。
doInBackground(Params…),后台进程执行的具体计算在这里实现,doInBackground(Params…)是AsyncTask的关键,此方法必须重载。在这个方法内可以使用publishProgress(Progress…)改变当前的进度值。
onProgressUpdate(Progress…),运行于UI线程。如果在doInBackground(Params…)中使用了publishProgress(Progress…),就会触发这个方法。在这里可以对进度条控件根据进度值做出具体的响应。
onPostExecute(Result),运行于UI线程,可以对后台任务的结果做出处理,结果就是doInBackground(Params…)的返回值。此方法也要经常重载,如果Result为null表明后台任务没有完成(被取消或者出现异常)。
这4个方法都不能手动调用。而且除了doInBackground(Params…)方法,其余3个方法都是被UI线程所调用的,所以要求:
1) AsyncTask的实例必须在UI thread中创建;
2) AsyncTask.execute方法必须在UI thread中调用;
Task只能被执行一次,多次调用时将会出现异常,而且是不能手动停止。
packagecn.asyn.rxm;
importandroid.app.Activity;
importandroid.os.AsyncTask;
importandroid.os.Bundle;
importandroid.util.Log;
importandroid.widget.TextView;
public classAsynctaskActivity extends Activity {
TextView tv;
final String TAG="AsyncTaskTest";
@Override
protected void onCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
tv =(TextView) findViewById(R.id.label);
newMyTask().execute(6, 12, 7);
}
class MyTask extendsAsyncTask<Integer, Integer, Integer>{
@Override
protectedvoid onPreExecute() {
super.onPreExecute();
Log.d(TAG,"onPreExecute()");
}
@Override
protectedInteger doInBackground(Integer... params) {
Log.d(TAG,"doInBackground()");
int p = 0;
for (int index = 0; index< params.length; index++) {
int num = params[index];
for (int j = 0; j < num; j++){
if (num -j <= 0) {
break;
}
p++;
publishProgress(p);
try{
Thread.sleep(500);
} catch(InterruptedException e) {
e.printStackTrace();
}
}
}
return p;
}
@Override
protectedvoid onProgressUpdate(Integer... progress) {
Log.d(TAG,"onProgressUpdate()");
tv.append("nProgress: " +progress[0]);
}
@Override
protectedvoid onPostExecute(Integer result) {
Log.d(TAG,"onPostExecute()");
tv.append("nFinished.Result: " + result);
}
@Override
protectedvoid onCancelled() {
super.onCancelled();
Log.d(TAG,"onCancelled()");
}
}
}