2012-05-19 54 views
0

我正在開發Android中的應用程序。應用程序可以向特定的Web服務器發佈HTTP請求。該發佈請求必須異步運行,因此我創建了一個線程來完成這項工作。但是我需要一個將在線程結束時調用的回調函數,並且它必須從調用`post`方法的線程調用。Android:從特定線程執行方法

post方法是這樣的:

interface EndCallback 
{ 
    public void Success(String response); 
    public void Fail(Exception e); 
} 

public void post(final String url, final List<NameValuePair> data, EndCallback callback) 
{ 
    Thread t = Thread.currentThread(); 
    (new Thread() 
    { 
     public void run() 
     { 
      HttpClient httpclient = new DefaultHttpClient(); 
      HttpPost httppost = new HttpPost(url); 
      try 
      { 
       httppost.setEntity(new UrlEncodedFormEntity(data)); 
       HttpResponse r = httpclient.execute(httppost); 

       HttpEntity en = r.getEntity(); 
       String response = EntityUtils.toString(en); 

       //I want to call callback.Success(response) 
       //here from thread t 
      } 
      catch (Exception ex) 
      { 
       //And I want to call callback.Fail(ex) 
       //here from thread t 
      } 
     } 
    }).start(); 
} 
+0

查看[無痛線程](http://developer.android.com/resources/articles/painless-threading.html)瞭解許多選項,包括Handler,AsyncTask或將Runnable實例發佈到活動或視圖。 –

回答

1

創建新主題的Android是高度氣餒於大多數應用。這似乎是AsyncTask的理想場所。它具有在線程之間切換的內置方法,無需手動管理線程創建。我已經在類似的情況下使用

一種方法是在任務有可能成功的美國enum結合:

class HttpPostTask extends AsyncTask<Void, Void, ResponseStatus> { 

    @Override 
    protected ResponseStatus doInBackground(Void... params){ 

     try { 
      // do your HTTP stuff 
      return ResponseStatus.SUCCESS; 
     } catch(Exception e){ 
      return ResponseStatus.FAILURE; 
     } 

    } 

    @Override 
    protected void onPostExecute(ResponseStatus status){ 
     switch(status){ 
     case SUCCESS: 
      // run your success callback 
      break; 
     case FAILURE: 
      // run the failure callback 
      break; 
     } 
    } 

} 

enum ResponseStatus { 
    SUCCESS, 
    FAILURE 
} 

doInBackground方法將在一個單獨的線程中運行,由操作系統管理。當該線程完成時,onPostExecute將在啓動任務的線程上運行,該任務通常是UI線程。

如果您需要設置回調對象,只需向HttpPostTask添加一個構造函數並執行所需的任何初始化。然後,您的客戶端代碼將只需要創建和執行任務:

new HttpPostTask().execute(); 

您也可以參數傳遞到​​爲好,這接受可變數量的類簽名的第一個通用類型的參數。 doInBackground中的params變量是傳遞給execute的所有相同類型的數組。

將參數傳遞到execute非常有用,例如,如果您想要發佈到多個URL。對於大多數依賴項,在構造函數中設置它們是最簡單的方法。

+0

完美答案......但是,我可以將參數傳遞給'execute()'方法嗎?或者我必須將這些參數傳遞給構造函數? –

+1

@NiyokoYuliawan - 是的,我剛剛更新了答案的結尾。 – derekerdmann

2

您可能需要使用一個處理程序。處理程序用於向GUI線程發送請求。

成功處理,使用下面的代碼:

final Handler successHandler = new Handler() 
{ 
    @Override 
    public void handleMessage(Message message) 
    { 
     callback.Success(response); 
    } 
}; 

successHandler.sendEmptyMessage(0);