2012-04-25 60 views
0

我想在啓動HttpClient的函數上實現一個線程,因爲它是根據d.android.com推薦的所以我已經實現了一個線程,但它似乎沒有運行,就好像我刪除線程代碼,我看到的結果。無法在Android中正確實現我的線程

這是我的代碼:

@Override 
public void onCreate(Bundle savedInstanceState) { 

    super.onCreate(savedInstanceState); 
    setContentView(R.layout.chat_box);// sd 
    TextView inbox = (TextView) findViewById(R.id.inbox); 
    final Functions function = new Functions(); 
    final SharedPreferences prefs = PreferenceManager 
      .getDefaultSharedPreferences(getBaseContext()); 
    where = prefs.getString("chat", "null"); 

    class SendThread extends Thread { 
      public void run(){ 
       //getInbox() runs an http client 
       listOfMessages = function.getInbox(where); 

      } 
     } 
    SendThread sendThread = new SendThread(); 
    sendThread.start(); 

    inbox.setText(listOfMessages); 

} 

就像我上面說的,如果我刪除我的線程代碼,然後將它完美的作品。關於我在做什麼的任何想法都是錯誤的?這是我第一次使用線程,對於任何新秀錯誤感到抱歉。

我沒有收到任何錯誤(至少我沒有看到任何錯誤),但是,我沒有看到沒有插入線程代碼的情況下得到的輸出。

+1

不要(嘗試)從不是UI線程的線程更改UI。另外,'inbox.setText(listOfMessages)'可能在'listOfMessages = function.getInbox(where);'之前執行。 – 2012-04-25 00:36:17

+0

它如何執行?我應該如何改變用戶界面,我正在盡力不要觸及任何觀點。 – EGHDK 2012-04-25 00:43:52

回答

2

我同意其他人:1)你沒有時間讓線程完成,2)你必須在主線程上修改UI。我想你可能希望看到一個具體的解決方案,所以在這裏你去:

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.chat_box);// sd 

    final Functions function = new Functions(); 
    final SharedPreferences prefs = PreferenceManager 
      .getDefaultSharedPreferences(getBaseContext()); 
    where = prefs.getString("chat", "null"); 
    new AsyncTask<String, Void, String>() { 
     @Override 
     protected String doInBackground(String... args) { 
      return function.getInbox(args[0]); 
     } 

     @Override 
     protected void onPostExecute(String result) { 
      TextView inbox = (TextView) findViewById(R.id.inbox); 
      inbox.setText(result); 
     } 

    }.execute(where); 
} 

使用的AsyncTask使得這款超級簡單:它是Android的推薦的方法做簡單的任務,關閉主線程。當調用execute()時,會創建一個新線程並調用doInBackground()。然後結果返回在主線程到onPostExecute方法。所以你不必處理runOnUiThread或其他任何東西。

在這種情況下需要注意的一件事:在類似於方向更改的情況下,您的活動將被銷燬並重新創建,因此調用getInbox()將再次被調用。這可能是也可能不是問題,取決於方法實際需要多長時間。如果它不可接受,則需要類似靜態AsyncTask的東西,但是會遇到附加到新Activity的問題。我只是提到這一點,不是因爲你現在必須處理它,而只是讓你知道。

+0

謝謝。你的整個解釋和代碼非常有用。我只有最後一個問題。我將如何去關於反覆運行這個線程? – EGHDK 2012-04-25 22:18:39

+0

您需要每次創建一個新的AsyncTask。如果你想多次這樣做,AsyncTask可能不是最好的方法。對於客戶端 - 服務器通信,我喜歡使用IntentService。 – 2012-04-26 04:15:39

0

您從線程獲得了listOfMessages的結果,但是您沒有將該列表發佈到收件箱TextView。該線程可能需要一段時間才能完全執行,但代碼

底部的線程一旦啓動就會執行。

所以,你需要調用inbox.setText(listOfMessages);一旦你的線程得到最新的listOfMessages。但是,您不能在非UI線程中執行任何UI操作(如setText)。

有很多選擇: 1.您可以在您的線程代碼中使用處理程序類,當您獲得listOfMessages時,可以使用處理程序並向UI線程發佈消息。你可以谷歌處理程序的樣本。

  1. 如果上面的代碼在您的活動中,您可以在活動中使用助手方法調用runOnUiThread。這是類似的。

    MyActivity.this.runOnUiThread(new Runnable(){inbox.setText(listOfMessages);});

希望這會幫助你。