2012-04-25 74 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);});

希望这会帮助你。