首页 > 代码库 > 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 }