0

我有这个代码:

    @Override
    public void onClick(View v) {
        if (!connected) {
            serverIpAddress = serverIp.getText().toString();
            if (!serverIpAddress.equals("")) {
                Thread cThread = new Thread(new ClientThread());
                cThread.start();                   
            }
        }
    }
};

private OnClickListener communicateListener = new OnClickListener() {

    @Override
    public void onClick(View v) {
        message = messageServer.getText().toString();
        if (!serverIpAddress.equals("")) {
            cThread.run();
            //Thread cThread = new Thread(new ClientThread());
            //cThread.start();
        }                  

    }
};

public class ClientThread implements Runnable {

    public void run() {           
          if (socket==null)
              connect to the server;
          else
              do smth else;
    }

我想要的是 connectListener 来创建线程和线程来建立连接。然后,在单击communicateListener 时,应用程序将从套接字读取或写入。我不知道如何实现这一点。

我应该以某种方式在communicateListener的onclick方法中再次调用线程吗?或者它是否在持续运行并且当套接字不是空时它会“做其他事情”?

我尝试再次调用运行函数,但我得到了 NullPointerException。当我在communicateListener 中创建一个新线程时它工作得很好,但我不想每次单击按钮时都创建一个新线程。

谢谢

4

2 回答 2

3

首先,永远不要调用线程的run()方法;这不会在新线程中运行代码,它会在您当前的线程中运行它。而是调用它的start()方法(以启动一个很快将在该run()方法处的新线程)。

当线程用完run()方法中的代码(或显式地从方法中返回)时,线程就结束了。该对象可能仍然存在,允许您从中提取数据(如果您想要任何东西),但是无法再次启动线程;您需要创建一个新实例并启动它。

如果您的意图是创建一次线程并让它在等待实际工作时“做其他事情”,您也可以这样做,但它与“在我需要工作时启动一个新线程”是不同的使用模型完毕”。两种使用模型都有自己的位置,但“当我需要它时启动”模型更易于实现,而且当它与 UI 操作相关时,更复杂的模型所提供的效率不太可能足以提升重要性。

于 2013-02-12T12:46:46.757 回答
1

在我看来,您在尝试使用它们之前没有阅读任何文档,因为很明显您对 Java 中的线程一无所知。如果我在哪里,我会阅读以下章节:http: //docs.oracle.com/javase/tutorial/essential/concurrency/

但总而言之,要使线程工作:您调用“start()”,线程将自行启动,并调用“run()”函数。当 run() 函数结束时,线程死亡。

因此,如果您想再次执行相同的操作,请创建一个新的线程实例,然后重新启动它。

于 2013-02-12T12:50:35.677 回答