2012-04-25 16 views
0

私はスレッドを実装しましたが、そうではありませんが、HttpClientを起動する関数でスレッドを実装しようとしています。私は結果を見るスレッドコードを削除するかのように実行する。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);'の前に実行されます。 –

+0

これはどのように実行することができますか? UIを変更するにはどのようにすればよいですか、どのビューにも触れないように最善を尽くしています。おかげさまで – EGHDK

答えて

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や何かを扱う必要はありません。

この場合、注意すべき点が1つあります。方向変更などの場合、アクティビティが破棄されて再作成されるため、getInbox()の呼び出しが再度呼び出されます。メソッドが実際にどのくらい時間がかかるかによって、これは問題になる場合もありません。容認できない場合は、静的なAsyncTaskのようなものが必要ですが、新しいアクティビティに戻ってくるという問題にぶつかります。私はちょうどそれを言及しています、あなたが今それを処理しなければならないからではなく、あなたが気づいているからです。

+0

あなたの全体の説明とコードはとても役に立ちました。私はちょうど最後の質問があります。どのように私はこのスレッドを何度も何度も実行するつもりですか? – EGHDK

+0

毎回新しいAsyncTaskを作成する必要があります。これを何度もやりたいのであれば、AsyncTaskはおそらく最良の方法ではありません。クライアントとサーバーの通信のために、私はIntentServiceを使いたい。 –

0

スレッドからlistOfMessagesの結果が得られましたが、そのリストを受信トレイのTextViewに投稿しませんでした。スレッドは完全に実行されるまでに時間がかかることがありますが、一度スレッドが開始されるとコード

inbox.setText(listOfMessages); 

が実行されます。

したがって、inbox.setText(listOfMessages)を呼び出す必要があります。スレッドが最新のlistOfMessagesを取得するとしかし、非UIスレッドでは、setTextのようなUI操作はできません。

多くの選択肢があります:1.スレッドコードでlistOfMessagesを取得したときにハンドラクラスを使用できます。ハンドラを使用してUIスレッドにメッセージを投稿できます。あなたはサンプルのためのGoogleのハンドラをすることができます。

  1. 上記のコードがあなたのアクティビティにある場合は、アクティビティでrunOnUiThreadを呼び出すヘルパーメソッドを使用できます。それはのようなものです。

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

希望すると、これが役立ちます。

関連する問題