如何停止或退出“Runnable”

时间:2013-04-24 10:10:43

标签: java android multithreading

我是android的新手。我正在构建应用程序以通过WiFi收听传入的消息,它可以正常用于收听和更新用户界面,但是当我尝试退出它时,它不响应后退按钮按直到它在缓冲区中接收消息。根据我的理解,按钮在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

    }

2 个答案:

答案 0 :(得分:2)

修改

现在你已经添加了涉及Handler的代码,现在你的问题就更清楚了。有些要点明白:

  • Android的一般概念是 主线程,然后还有很多其他线程。
  • 只有主线程可以修改UI
  • 在Android的后续版本中,主线程不允许进行联网......

那么如何根据从网络中读取内容来更改UI?

您需要将消息从另一个(网络)线程传递到主线程。 Handler让你的另一个线程给主线程发一条消息......那就是你的网络线程可以给主线程执行任务(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()而不是run()以使run方法在其自己的线程中执行。使用线程的全部意义在于,一个线程不会(通常)被另一个忙线阻塞。

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

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

答案 1 :(得分:-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;
         }
     }
 }