2010-08-02 68 views
17

我有一個應用程序在用戶單擊某些按鈕時執行HTTP請求(特別是調用FogBugz API)。現在,我只是在應用程序啓動時創建一個服務,然後調用該服務中的不同方法來完成請求。但是,當我這樣做時,UI線程中通常會掛起。我已經看過AsyncTask,但我不確定它會做我想完成的事情。因爲我需要立即解析HTTP請求返回的XML,所以我需要一個能夠將此數據返回給UI線程的進程。 ASyncTask能做到這一點,還是有其他方法?如何使用單獨的線程執行http請求

public static InputStream makeRequest(String httpRequest) 
    { 
     In a separate thread, run HTTP Request, get back and process, return inputstream 
    } 

這個方法被其他幾個人調用來執行HttpRequests。一旦輸入流返回,其他方法解析特定的信息。

回答

59

做到這純粹是做類似

//Body of your click handler 
Thread thread = new Thread(new Runnable(){ 
    @Override 
    public void run(){ 
    //code to do the HTTP request 
    } 
}); 
thread.start(); 

這將導致run()方法裏面的代碼在一個新的執行線程來執行的最簡單方法。如果您喜歡,您可以查看異步任務,儘管我個人從未使用它。這是一個快速簡單的方法來完成任務。

關於傳回信息,我會使用Handler object,它有效地允許您爲給定線程設置消息隊列並將消息傳遞給它,從而導致執行特定代碼。您需要這樣做的原因是因爲Android不會讓UI線程以外的任何線程更新實際的UI。

這是否解決您的問題?我知道我的第一通並沒有完全解決你所有的問題。

編輯基本上,你要做的就是在你的Activity定義處理對象像

private Handler handler_ = new Handler(){ 
    @Override 
    public void handleMessage(Message msg){ 

    } 

}; 

您還可以創建靜態int常量,幫助告訴處理器做什麼。您基本上使用這些來允許將幾種不同類型的消息傳遞給處理程序的一個實例。如果只有一條消息傳回去,那麼你不必擔心這一點。

例如

private static final int UPDATE_UI = 1; 

要發送消息給你打電話

handler_.sendMessage(Message.obtain(handler_, UPDATE_UI, inputStreamInstance)); 

從處理程序的處理程序:

private Handler handler_ = new Handler(){ 
    @Override 
public void handleMessage(Message msg){ 
    switch(msg.what){ 
      case UPDATE_UI: 
      InputStream is = (InputStream)msg.obj; 
      //do what you need to with the InputStream 
      break; 
     } 
    } 

}; 

或者,在inputStreamInstance添加到Message對象,如果你想解析它,你可以傳遞任何你喜歡的對象對某種容器對象或類似的東西,你也可以這樣做。只需從處理程序中將其重新轉換回該對象即可。

+0

感謝您的幫助http請求的程序。關於從單獨的線程發送和接收信息,我仍然遇到一些麻煩。我更新了我的問題,希望能夠澄清我需要做的事情。關於Handler對象,我會在輔助線程中使用它來傳回信息,例如輸入流? – mbauer14 2010-08-02 20:22:41

4

嘗試使用AsyncTask。後藤本Link更多:

private class SyncIncoData extends AsyncTask<String, String, String> { 
    ProgressBar pb; 
    ProgressBar pbar; 

    @Override 
    protected String doInBackground(String... urls) { 
     for (int i = 0; i <= 100; i++) { 
      publishProgress(i); 
     } 
     return null; 
    } 

    @Override 
    protected void onPreExecute() { 

     super.onPreExecute(); 

     pb = (ProgressBar) findViewById(R.id.progressBarsync4); 
     pb.setVisibility(View.VISIBLE); 

    } 

    @Override 
    protected void onPostExecute(String result) { 

     pb = (ProgressBar) findViewById(R.id.progressBarsync4); 
     pb.setVisibility(View.INVISIBLE); 

    } 

    @Override 
    protected void onProgressUpdate(String... values) { 
     pbar = (ProgressBar) findViewById(R.id.progressBarpbar); 
     pbar.setProgress(Integer.parseInt(values[0])); 
     super.onProgressUpdate(values); 
    } 
} 

寫出內doinbackgroud()