Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/198.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java “如何停止或退出”;“可运行”;_Java_Android_Multithreading - Fatal编程技术网

Java “如何停止或退出”;“可运行”;

Java “如何停止或退出”;“可运行”;,java,android,multithreading,Java,Android,Multithreading,我是android新手。我正在构建一个应用程序,可以通过WiFi监听传入的消息,它可以很好地监听和更新UI,但当我尝试退出时,它不会响应返回按钮,直到它在缓冲区中接收到消息。据我所知,按钮在UI线程上,Runnable是一个单独的线程,这就是为什么它不会立即响应按钮按下,因为它在单独的线程上很忙。那么,如何从按下后退按钮时中断“Runnable” 任何帮助都将不胜感激 public Runnable mUpdate = new Runnable() { public void run()

我是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

    }
编辑:

现在,您已经添加了涉及的代码,现在您的问题所在就更清楚了。需要了解的一些要点:

  • 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是一个单独的线程,这就是为什么它不会立即响应按钮按下,因为它在单独的线程上很忙

那完全不对。 是一个单独的线程,而不是可运行的线程。您需要在线程上调用
start()
而不是
run()
,以使run方法在自己的线程中执行。使用线程的全部意义在于,一个线程不会(通常)被另一个线程阻塞

// <snip>removed for brevity of new answer</snip>
//为了新答案的简洁,删除了

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

我不知道这与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;
         }
     }
 }

interrupt()
仅设置中断标志。执行的代码负责检查此标志并正确终止。@afk5min是和否。虽然在这种情况下更多的是而不是否。根据线程的当前状态,它确实有其他影响。我已经修改了答案来解决这个问题。如果线程处于阻塞等待状态,则会生成InterruptedException,但会检查该异常;执行的代码被强制处理这种情况。(另外,上面的示例不使用阻塞等待)同意。。。因此“是多于否”:-)谢谢你的时间,我还没有尝试你的答案,我会尝试,然后我会标记你的答案@coullingonly
Thread#stop()
方法使用JVM/本机方法杀死正在执行的线程<代码>中断()。我忘了添加while(true)循环。请参阅我的编辑。那会让你快乐吗?另外,如果不是一些本机API(POSIX线程、Solaris线程、Windows线程等),您认为中断是如何在内部完成的?设置一个标志可能是正确的,但这取决于实现,而javadoc中对此没有任何规定。;)@这很有趣!不,真的,请阅读来自Android项目和非Android项目的中断文档。它们不同。这就是为什么我以“我不知道这是否与Android有关”开头的原因:)另外,我还忘记了中断被捕获后的break语句,我甚至没有编译它-只是一个提示,在纯JAVA中,它应该用中断来完成。@couling-InputStream,Socket。。什么?我只是根据题目提问,我认为这是显而易见的。“我将不再参与这个无用的讨论。”库林我刚刚打开eclipse并编写了这个。这很有道理——线程。睡眠缺失。这是如此明显,我甚至没有想到它。干杯