【轉】 Pro Android學習筆記(九三):AsyncTask(2):小例子

目錄(?)[-]程序員

  1. 繼承AsyncTask
  2. UI操做接口
  3. 使用AsyncTask

文章轉載只能用於非商業性質,且不能帶有虛擬貨幣、積分、註冊等附加條件。轉載須註明出處:http://blog.csdn.net/flowingflying/編程

小例子app

經過簡單的菜單,觸發一個用sleep模擬的任務。Test Async One 1將調用1個AsyncTask任務,咱們在Test Ansync One 2中同時執行兩個task,看看運行的狀況。Test Async Two中互動會更爲複雜,task不只在主線程寫TextView,還開啓一個ProgessDialog。ide

繼承AsyncTask

咱們先經過Test Async One 1來學習AsyncTask。首先實現繼承AsyncTask。函數

public class MyLongTask extends AsyncTask<String,Integer,Integer>
    private IReportBack report = null; 
    private String tag = null; 
    //【步驟1】:構造函數,IReportBack定義主線程Activity處理task UI操做的回調函數,做爲良好編程風格,無需將Activity對象直接傳遞過來。
    public MyLongTask(IReportBack inr, String inTag){ 
        report = inr; 
        tag = inTag; 
    } 
    
    @Override //【步驟2】:重寫onPreExecute(),這是運行在主線程中(準確來將是運行在建立對象所在線程),進行後臺線程運行先的初始化等處理。因爲運行在主線程,所以可在此進行UI操做。
    protected void onPreExecute()
 {  
        Log.v(tag, "onPresExecute():" + Utils.getThreadSignature());
        report.reportTransient(tag, "In progress ...... ");  //調用接口中的UI處理函數。       
    } 

    @Override //【步驟4】從程序員的視圖,在worker線程中運行的doInBackground(),經過publishProgress()觸發在主線程運行的的onProgressUpdate(),當中的機制是handler。在此,咱們進行在其餘線程運行時須要觸發的UI處理。
    protected void onProgressUpdate(Integer... values)
 {  
        Log.v(tag, "onProgressUpdate():" + Utils.getThreadSignature());                 
        Integer i = values[0]; 
        report.reportBack(tag, "Progress: i = " + i);//調用接口中的UI處理函數。
    } 

    @Override //【步驟5】當後臺線程運行完,經過handler將最後結果通知給線程,將在主線程觸發onPostExcute(),在此進行後臺處理結束觸發相關的UI處理。參數result爲doInbackground()的返回值。
    protected void onPostExecute(Integer result)
 {  
        Log.v(tag, "onPostExecute():" + Utils.getThreadSignature()); 
        report.reportBack(tag, "result: i = " + result);         
    }      
     
    @Override //【步驟3】當調用task.execute()時,將在worker線程中執行doInBackground(),因爲不在主線程中執行,不能再此進行UI操做,若是但願觸發相關的UI操做,經過publishProgress(),利用隱藏的handler在主線程隊列加入message進行處理。主線程處理message,觸發handler的handleMessage(),這些隱藏的步驟經過AsyncTask的封裝,呈現爲觸發onProgressUpdate()。
    protected Integer doInBackground(String... params)
 {  
        Log.v(tag,"doInBackground():" + Utils.getThreadSignature());
       for(int i = 0; i < params.length;i ++){ 
            Utils.sleepForSecs(2); //休眠2秒 
            publishProgress(i); 
        }        
        return params.length; 
    } 
}學習

UI操做接口

AsyncTask封裝得很是好,提升task運行前、運行中、運行後的回調函數,在此咱們進行相關的UI處理。這些代碼都放在對AsyncTask繼承類中。處理UI就離不開Activity的View,最直接的方式是將Activity對象經過構造函數傳遞到AsyncTask中,然而在真正的項目開發,這樣作會使一個特定的任務能夠任意調用Activity的功能,二者的界面不清晰,代碼可讀性、可維護性,檢查錯誤方面都不太好。所以,一般會將task涉及到的UI處理放入到接口中。this

public interface IReportBack { 
    public void reportBack(String tag,String message); 
    public void reportTransient(String tag,String message); 
}.net

使用AsyncTask

咱們將在主線程中建立AsyncTask對象,下面是activity的相關代碼線程

public class MainActivity extends Activity implements IReportBack{
    private static TextView tv = null; 
    … … 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
        int id = item.getItemId(); 
        if (id == R.id.testOne1){ 
            testMyLongTask(); 
        } 
        return super.onOptionsItemSelected(item); 
    } 
    
    private void testMyLongTask(){ 
        MyLongTask task = new MyLongTask(this,  "TestOne");  //建立AsyncTask對象,經過這個對象,咱們能夠經過調用task.cancel()來中止worker線程,這時會觸發onCanceled(Object)回調函數。 
        task.execute("Hello","my","friend");    //經過execute() 來觸發後臺線程執行,順序在主線程運行onPreExecute(),而後開線程運行doInBackground()的代碼,doInBackground運行結束後,觸發在主線程運行的onPostExecute()。
    } 
      
    @Override //接口實現
    public void reportBack(String tag, String message) {  
        tv.append(tag + " : " + message + "\n"); 
        Log.v(tag,message); 
    } 

   @Override //接口實現
    public void reportTransient(String tag, String message) {  
        Toast.makeText(this, tag + " : " + message, Toast.LENGTH_SHORT).show();
        reportBack(tag,message); 
    } 

對象

 

相關小例子源代碼可在Pro Android學習:AsyncTask小例子中下載。

相關連接: 個人Android開發相關文章

相關文章
相關標籤/搜索