Android1.5开始引入了AsyncTask类。实现了简单的异步线程。使得我们可以在后台进程中做一些耗时的工作,并可调用 publishProgress来更新主线程中的UI。
以下是一个简单的例子。
一、Activity
新建Android project。Android SDK版本1.5以上。程序只有一个Activity。
布局文件很简单,就一个TextView,就不贴xml代码了,直接看java代码:
- public class main extends Activity {
- private TextView tv;
- private MyTask task;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
-
- tv = (TextView) findViewById(R.id.tv_progress);
-
- task=new MyTask();
-
- task.execute(tv);
- }
- }
二、AsyncTask类
关键是MyTask的代码:
- public class MyTask extends AsyncTask<object, integer,="" integer=""> {
- private TextView tv;
-
- @Override
- protected void onPreExecute() {
- super.onPreExecute();
- }
- @Override
- protected Integer doInBackground(Object... params) {
- tv = (TextView) params[0];
- int i;
-
- for (i = 1; i <= 20; i++) {
- publishProgress(i);
- try {
- Thread.sleep(500);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- return i;
- }
-
- @Override
- protected void onProgressUpdate(Integer... progress) {
- int i=progress[0];
- switch(i%6){
- case 1:
- tv.setText("等待服务器响应: ." );
- break;
- case 2:
- tv.setText("等待服务器响应: . ." );
- break;
- case 3:
- tv.setText("等待服务器响应: . . ." );
- break;
- case 4:
- tv.setText("等待服务器响应: . . . ." );
- break;
- case 5:
- tv.setText("等待服务器响应: . . . . ." );
- break;
- case 0:
- tv.setText("等待服务器响应: . . . . . ." );
- break;
- }
- }
-
- @Override
- protected void onPostExecute(Integer result) {
- tv.setText("完成。");
- }
-
- @Override
- protected void onCancelled() {
- super.onCancelled();
- }
- }
MyTask类的声明很奇怪,使用了3个范型:Object,Integer,Integer。
第1个范型指定了 doInBackground方法的参数类型是一个不定长的Object数组。
我们这样定义是因为,当主线程中用execute 方法启动MyTask线程时,我们会传递一些参数给doInBackground方法。虽然这个例子里我实际只传递了一个TextView参数(用于在 Task中更新文字标签的内容)。但作为扩展,我在未来还想传递另一个参数,比如url(类型为java.net.URL),这样,我只好把第1个范型指 定为层次比抽象的Object类型了。
第2个范型指定了 onProgressUpdate方法的参数类型为Integer不定长数组。因为这个方法只会在调用 publishProgress 方法时调用,而我们只在 doInBackground方法中调用过 publishProgress方法。我们只需传递一个表示进度的整数给它就可以了。
第3个范型指定了 onPostExecute方法的参数类型。同样,使用Integer类型就可以了。
上面提到的3个方法是AsyncTask的核心方法。
doInBackground 方法在线程被execute启动时调用(只有一次)。在该方法中,建立线程循环以完成某些工作。在每次循环完成时,我们通过手动调用 publishProgress方法,通知onProgressUpdate方法更新主线程的UI(调用多次)。当所有循环完成后,线程循环结束,自动调 用onPostExecute方法返回结果(调用一次),线程销毁。
从上可知,除execute和publishProgress方法外的其他方法 ,我们都不应该直接调用。
(kmyhy) |