代码改变世界

android解决UI阻塞问题——创建AsyncTask 子线程

2011-08-22 18:00  myjava2  阅读(314)  评论(0编辑  收藏  举报
  1. view plaincopy to clipboardprint?  
  2. view plaincopy to clipboardprint?    
  3. package net.blogjava.mobile.wsclient;       
  4.         
  5. import org.ksoap2.SoapEnvelope;       
  6. import org.ksoap2.serialization.SoapObject;       
  7. import org.ksoap2.serialization.SoapSerializationEnvelope;       
  8. import org.ksoap2.transport.HttpTransportSE;       
  9. import android.app.Activity;       
  10. import android.os.AsyncTask;       
  11. import android.os.Bundle;       
  12. import android.view.View;       
  13. import android.view.View.OnClickListener;       
  14. import android.widget.Button;       
  15. import android.widget.EditText;       
  16. import android.widget.TextView;       
  17.         
  18. public class Main extends Activity implements OnClickListener       
  19. {       
  20.     private EditText etProductName;       
  21.     private TextView tvResult;       
  22.         
  23.     class WSAsyncTask extends AsyncTask       
  24.     {       
  25.         String result = "";       
  26.         @Override       
  27.         protected Object doInBackground(Object... params)       
  28.         {       
  29.             try       
  30.             {       
  31.                 String serviceUrl = "http://192.168.17.156:8080/axis2/services/SearchProductService?wsdl";       
  32.                 String methodName = "getProduct";       
  33.                 SoapObject request = new SoapObject("http://service",       
  34.                         methodName);       
  35.                 request.addProperty("productName", etProductName.getText().toString());       
  36.                 SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(       
  37.                         SoapEnvelope.VER11);       
  38.                 envelope.bodyOut = request;       
  39.                 HttpTransportSE ht = new HttpTransportSE(serviceUrl);       
  40.         
  41.                 ht.call(null, envelope);       
  42.                 if (envelope.getResponse() != null)       
  43.                 {       
  44.                     SoapObject soapObject = (SoapObject) envelope.getResponse();       
  45.                     result = "产品名称:" + soapObject.getProperty("name") + "\n";       
  46.                     result += "产品数量:" + soapObject.getProperty("productNumber")       
  47.                             + "\n";       
  48.                     result += "产品价格:" + soapObject.getProperty("price");       
  49.         
  50.                 }       
  51.                 else       
  52.                 {       
  53.                     result = "无此产品.";       
  54.                 }       
  55.             }       
  56.             catch (Exception e)       
  57.             {       
  58.                 result = "调用WebService错误.";       
  59.             }       
  60.             // 必须使用post方法更新UI组件       
  61.             tvResult.post(new Runnable()       
  62.             {       
  63.                 @Override       
  64.                 public void run()       
  65.                 {       
  66.                     tvResult.setText(result);       
  67.         
  68.                 }       
  69.             });       
  70.             return null;       
  71.         }       
  72.         
  73.     }       
  74.     @Override       
  75.     public void onClick(View view)       
  76. {       
  77.     // 异步执行调用WebService的任务         
  78.         new WSAsyncTask().execute();       
  79.     }       
  80.     @Override       
  81.     public void onCreate(Bundle savedInstanceState)       
  82.     {       
  83.         super.onCreate(savedInstanceState);       
  84.         setContentView(R.layout.main);       
  85.         Button btnSearch = (Button) findViewById(R.id.btnSearch);       
  86.         btnSearch.setOnClickListener(this);       
  87.         etProductName = (EditText) findViewById(R.id.etProductName);       
  88.         tvResult = (TextView) findViewById(R.id.tvResult);       
  89.         
  90.     }       
  91. }     

1. 一般需要编写一个AsyncTask的子类来完成后台执行任务的工作。
2.  AsyncTask的核心方法是doInBackground,当调用AsyncTask类的execute方法时,doInBackground方法会异步执行。因此,可以将执行任务的代码写在doInBackground方法中。
3. 由于本例中的TextView组件是在主线程(UI线程)中创建的,因此,在其他的线程(doInBackground方法所在的线程)中不能直接更新TextVew组件。为了更新TextView组件,需要使用TextView类的post方法。该方法的参数是一个Runnable对象,需要将更新TextView组件的代码写在Runnable接口的run方法中。
4. 虽然不能在其他线程中更新UI组件,但可以从其他线程直接读取UI组件的值。例如,在doInBackground方法中直接读取了EditText组件的值。
5. 调用AsyncTask类的execute方法后会立即返回。execute方法的参数就是doInBackground方法的参数。doInBackground方法的返回值可以通过AsyncTask.execute(...).get()方法获得。
读者可以将本例中的IP改成其他的值,看看单击按钮后,是否还可在文本框中输入其他的内容。如果这个IP是正确的,并且WebService可访问,那么会在TextView组件中输出相应的返回值。