首页 > 代码库 > Android AsyncTask

Android AsyncTask

  做过android开发的朋友们都知道,Android UI线程(或者叫主线程)是不安全的,如果想要在子线程里进行UI操作,就需要借助android的异步消息处理机制。最近学习了AsyncTask类,感觉很好用,特此学习总结。

  AsyncTask是一个抽象类,所以我们在使用的时候需要创建一个子类继承它。继承时我们需要为AsyncTask类指定3个泛型参数。如下所示:

public class xx extends AsyncTask<Params, Progress, Result>{        } 
Params, Progress, Result,3个参数的用途如下:
1.Params
  在执行AsyncTask 时需要传入的参数,可用于在后台任务中使用。
2.Progress
  后台任务执行时,如果需要在界面上显示当前的进度,则使用这里指定的泛型作为进度单位。
3.当任务执行完毕后,如果需要对结果进行返回,则使用这里指定的泛型作为返回值类型。
如下是我在写一个有关android平台调用webservice时用到的
public class getRemoteInfoTask extends AsyncTask<Void,Integer, String>    {        @Override        protected String doInBackground(Void... arg0) {            // TODO 自动生成的方法存根            return getRemoteInfo(QueryNumber);        }                @Override        protected void onPostExecute(String result)        {            text_result.setText(result);            super.onPostExecute(result);        }            }

  我们可以看到,第一个参数即Params被指定为Void,表示不需要传入参数;第二个参数即Progress被指定为Integer,表示使用整型数据来作为进度显示单位;第三个参数被指定为String,表示使用String数据来反馈执行结果。

  在以上例子中,我重写了2个函数,也是最基本最常用的2个函数,除此之外,经常需要重写的函数有如下四个:

  1. onPreExecute()
  这个方法会在后台任务开始执行之间调用,用于进行一些界面上的初始化操作,比如显示一个进度条对话框等。
  2. doInBackground(Params...)
  这个方法中的所有代码都会在子线程中运行,我们应该在这里去处理所有的耗时任务。任务一旦完成就可以通过return 语句来将任务的执行结果进行返。在这个方法中是不可以进行UI 操作的,如果需要更新UI 元素,比如说反馈当前任务的执行进度,可以调用publishProgress(Progress...)方法来完成。
  3. onProgressUpdate(Progress...)
  当在后台任务中调用了publishProgress(Progress...)方法后,这个方法就很快会被调用,方法中携带的参数就是在后台任务中传递过来的。在这个方法中可以对UI 进行操作,利用参数中的数值就可以对界面元素进行相应的更新。
  4. onPostExecute(Result)
  当后台任务执行完毕并通过return 语句进行返回时,这个方法就很快会被调用。返回的数据会作为参数传递到此方法中,可以利用返回的数据来进行一些UI 操作,比如说提醒任务执行的结果,以及关闭掉进度条对话框等。

  调用执行

new getRemoteInfoTask().execute();

  以下是通过webservice获取号码归属地的例子,其中就用到了AsyncTask类

 1 package com.example.webservice; 2  3 import java.io.IOException; 4  5 import org.apache.http.HttpServerConnection; 6 import org.ksoap2.SoapEnvelope; 7 import org.ksoap2.serialization.SoapObject; 8 import org.ksoap2.serialization.SoapSerializationEnvelope; 9 import org.ksoap2.transport.HttpTransportSE;10 import org.xmlpull.v1.XmlPullParserException;11 12 import android.app.Activity;13 import android.os.AsyncTask;14 import android.os.Bundle;15 import android.view.View;16 import android.widget.EditText;17 import android.widget.TextView;18 19 public class MainActivity extends Activity {20     21     private EditText edit_poneNumber;22     private TextView text_result;23     private String QueryNumber;24     25     //WSDL文档中的命名空间和方法26     private static final String targetNameSpace = "http://WebXml.com.cn/";27     private static final String function = "getMobileCodeInfo";28     private static final String WSDL = "http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx?wsdl";29     30 31     @Override32     protected void onCreate(Bundle savedInstanceState) {33         super.onCreate(savedInstanceState);34         setContentView(R.layout.activity_main);35         36         edit_poneNumber = (EditText)findViewById(R.id.edit_phone_sec);37         text_result = (TextView)findViewById(R.id.result_text);38     }39     public void onQuety(View v)40     {41         QueryNumber = edit_poneNumber.getText().toString();42         if("".equals(QueryNumber.trim()) || QueryNumber.length() < 7)43         {44             edit_poneNumber.setError("输入有误");45             edit_poneNumber.requestFocus();46             text_result.setText("");47             return;48         }49         // 查询手机号码(段)信息50         new getRemoteInfoTask().execute();51     }52     /**53      * 手机号段归属地查询54      * 55      * @param phoneSec 手机号段56      */57     public class getRemoteInfoTask extends AsyncTask<Void, Void , String>58     {59         @Override60         protected String doInBackground(Void... arg0) {61             // TODO 自动生成的方法存根62             return getRemoteInfo(QueryNumber);63         }64         65         @Override66         protected void onPostExecute(String result)67         {68             text_result.setText(result);69             super.onPostExecute(result);70         }71         72     }73     public String getRemoteInfo(String phoneSec) 74     {75         String result = null;76         SoapObject soapObject = new SoapObject(targetNameSpace, function);77         soapObject.addProperty("mobileCode", QueryNumber);78         soapObject.addProperty("userID", null);79         SoapSerializationEnvelope envelop = new SoapSerializationEnvelope(SoapEnvelope.VER11);        80         envelop.dotNet = true;81         envelop.setOutputSoapObject(soapObject);//或者envelop.bodyOut = soapObject;82         HttpTransportSE httpSE = new HttpTransportSE(WSDL);83         try {84             httpSE.call(targetNameSpace+function, envelop);85             SoapObject resultObj = (SoapObject) envelop.bodyIn;86             result = resultObj.toString();87         } catch (IOException e) {88             // TODO 自动生成的 catch 块89             e.printStackTrace();90         } catch (XmlPullParserException e) {91             // TODO 自动生成的 catch 块92             e.printStackTrace();93         }94         return result;95     }96 }