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     @Override
32     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         @Override
60         protected String doInBackground(Void... arg0) {
61             // TODO 自动生成的方法存根
62             return getRemoteInfo(QueryNumber);
63         }
64         
65         @Override
66         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 }

Android AsyncTask,布布扣,bubuko.com

Android AsyncTask

上一篇:iOS UIWebView 通过 cookie 完成自动登录验证


下一篇:iOS: 学习笔记, 值与引用类型(译自: https://developer.apple.com/swift/blog/ Aug 15, 2014 Value and Reference Types)