我有这段代码:
@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来创建线程和建立连接的线程。然后,在单击communicListener时,应用程序将从套接字读取或写入其中。我不知道如何实现这个。
我应该在communicListener的onclick方法中以某种方式再次调用该线程吗?或者它是否继续运行,当socket不是null时它会“做其他事情”吗?
我尝试再次调用run函数但是我得到了一个NullPointerException。当我在communicListener中创建一个新线程时,它工作得非常好,但我不希望每次单击按钮时都创建一个新线程。
谢谢
答案 0 :(得分:3)
首先,永远不要调用Thread的run()
方法;它不会在新线程中运行代码,它会在当前线程中运行它。改为调用其start()
方法(以启动即将采用run()
方法的新线程。)
当线程用尽run()
方法中的代码(或显式返回方法)时,线程结束。对象可能仍然存在,允许您从中提取数据(如果有任何需要的话),但是线程无法再次启动;你需要创建一个新实例并改为启动它。
如果您打算创建一个线程,并在等待实际工作时让它“做其他事情”,那么您也可以这样做,但它是一个不同的使用模型,而不是“当我启动一个新线程需要我的工作完成“。两种使用模型都有它们的位置,但是“当我需要它时启动它”模型更容易实现,并且当它与UI操作相关联时,更复杂模型给出的效率不足以提升物质。
答案 1 :(得分:1)
在我看来,在尝试使用它们之前,你还没有读过任何文档,因为很明显你对java中的线程没有了解。如果我在哪里,我会阅读以下章节:http://docs.oracle.com/javase/tutorial/essential/concurrency/
但总而言之,要使线程工作:你调用“start()”,线程将自动启动,并调用“run()”函数。 当run()函数结束时,线程就会死掉。
因此,如果您想再次执行相同的操作,请创建一个新的线程实例,然后重新启动它。