4

我是 android 新手。我正在构建应用程序以通过 WiFi 监听传入消息,它可以很好地监听和更新 UI,但是当我尝试退出时,它不会响应后退按钮按下,直到它在缓冲区中接收到消息。据我了解,按钮在 UI 线程上,而 Runnable 是一个单独的线程,这就是为什么它不会立即响应按钮按下,因为它在单独的线程上很忙。那么我如何从后退按钮按下中断“Runnable”?

任何帮助将非常感激。

public Runnable mUpdate = new Runnable() {
    public void run() {            
        try {   
            line = in.readLine();
            newtext.setText(line);
            mHandler.post(this);
            Log.i("RESPONSE FROM SERVER", "S: Received Message: '" +line+ "'");

            //onBackPressed();
            //threadRunning = true;
        } catch (IOException e) {
            // TODO Auto-generated catch block
            Log.e("Error" , "Something Happen");    
        }
    }
};  

编辑:对不起,我应该早点发布这个,所以在“onCreate”中,我使用处理程序来调用“mUpdate”。打电话的方式是否正确?

    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    intent = getIntent();
    setContentView(R.layout.activity_display_message);
    message = intent.getStringArrayExtra(MainActivity.EXTRA_MESSAGE);
    newtext = (TextView)findViewById(R.id.TextView1);
    userName = message[0];
    serverIP = message[1];
    sendConnectionRequest ();
    mHandler = new Handler();   // Handler to update UI      
    mHandler.post(mUpdate);     // post is a method to update UI

    }
4

2 回答 2

2

编辑:

既然您已经添加了涉及Handler的代码,那么您的问题所在就更清楚了。需要理解的几点:

  • Android有一个普遍的概念,即有线程,然后有许多其他线程。
  • 只有主线程可以修改 UI
  • 在更高版本的android中,主线程不允许做网络......

那么如何根据从网络上读取的东西来改变 UI 呢?

您需要将消息从另一个(网络)线程传递到主线程。处理程序让您的其他线程向主线程发送消息......那是您的网络线程可以将任务(Runnable)交给主线程执行。处理程序将任务从网络线程发布到主线程。

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    intent = getIntent();
    setContentView(R.layout.activity_display_message);
    message = intent.getStringArrayExtra(MainActivity.EXTRA_MESSAGE);
    newtext = (TextView)findViewById(R.id.TextView1);
    userName = message[0];
    serverIP = message[1];
    sendConnectionRequest ();
    mHandler = new Handler();   // Handler to update UI  
                                // This is being created in the main thread
                                // so everything posted will be posted to 
                                // the main thread

    mUpdate.start();            // start thread to do something on the network 
                                //before updating the UI

}

public Thread mUpdate = new Thread() {
    public void run() {            
        try {
            while (!thread.interrupted()) {   
                final String line = in.readLine();
                Log.i("RESPONSE FROM SERVER", "S: Received Message: '" +line+ "'");

                // Define the UI change you want to make
                Runnable uiUpdate = new Runnable() {
                    public void run() {
                        // modify your UI here.
                        newtext.setText(line);
                    }
                };

                // post the UI change back to the main thread.
                mHandler.post(uiUpdate);
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            Log.e("Error" , "Something Happen");    
        }
    }

    public void interrupt() {
        try {
            super.interrupt();
            in.close();
        }
        catch (IOException e) {}
    }
}; 

我也可以建议你:

protected void onDestroy() {
    mUpdate.interrupt();
}

原始答案(现已失效)

据我了解,按钮在 UI 线程上,而 Runnable 是一个单独的线程,这就是为什么它不会立即响应按钮按下,因为它在单独的线程上很忙。

这根本不正确。Thread是一个单独的线程,而不是 Runnable。并且您需要在线程上调用start()notrun()以使 run 方法在自己的线程中执行。使用线程的全部意义在于一个线程不会(通常)被另一个正忙的线程阻塞。

// <snip>removed for brevity of new answer</snip>

您还可以从 android 库中查看AsyncTask 。如果你正确使用它,它也会在它自己的线程中运行。

于 2013-04-24T10:24:33.700 回答
-1

我不知道这与 Android 有什么关系,但从你的标题来看,停止 Java 中的线程是通过中断完成的,而中断是由操作系统本身处理的。

从你的线程你打断另一个。

theOtherThread.interrupt() //--> inside your Thread.

另一方面:

 public void run(){
     while(true){
          try{
               //handle your logic
               Thread.sleep(100);
          }catch(InterruptedException){
             //thread was 'stopped' here
             Thread.currentThread().interrupt(); //this is a MUST
             break;
         }
     }
 }
于 2013-04-24T11:13:50.687 回答