我有一个服务,它启动线程在套接字上执行一些操作。代码如下:
public class ServerRunnable implements Runnable {
@Override
public void run() {
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket();
serverSocket.setReuseAddress(true);
serverSocket.bind(new InetSocketAddress(ProtocolConstants.USB_SERVER_PORT));
while (true) {
Socket client = serverSocket.accept();
// some code
} catch (Exception e) {
Log.e("Exception while listening on socket.", e);
} finally {
if (serverSocket != null) {
try {
serverSocket.close();
} catch (IOException e) {
Log.e(e);
}
}
}
当我第一次启动服务时,一切都很好,但后来我必须使用停止它stopService
方法。当我再次启动它时,它返回以下异常:
java.net.BindException: bind failed: EADDRINUSE (Address already in use)
另外我添加了ServerSocket
逼进onDestroy
服务方法但没有帮助。
The setReuseAddress
之前执行bind
,那么为什么它不起作用呢?
据我猜测它会卡住serverSocket.accept()
,等待连接进入。因此,即使关闭应用程序后,Runnable 也永远不会完成。再次调用应用程序会出现此错误(因为端口仍然被之前创建的 Runnable 阻止)。有多种方法可以处理这个问题:
-
您可以像这样调用并停止您的 Runnable:
ThreadPoolExecutor threadPoolExecutor = Executors.newSingleThreadExecutor();
Runnable longRunningTask = new Runnable();
Future longRunningTaskFuture = threadPoolExecutor.submit(longRunningTask);
longRunningTaskFuture.cancel(true); //this might not trigger right away
您可以停止serverSocket.accept()
通过致电serversocket.close()
(这会抛出需要处理的SocketException)
-
我通过从服务器发送数据(字符串)到我的 serverSocket 解决了这个问题(可能不是处理这个问题的正确方法)onClose()
我的活动中的方法:
Socket socket = new Socket();
socket.setReuseAddress(true);
socket.connect((new InetSocketAddress(YOURSETTINGS, HERE);
OutputStream os = socket.getOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(os);
oos.writeObject(new String("TIMEOUT"));
oos.close();
os.close();
socket.close();
您可以选择在服务器中捕获它,如下所示:
ObjectInputStream objectInputStream = new objectInputStream(serverSocket.getInputStream());
Object object = objectInputStream.readObject();
if (object.getClass().equals(String.class) && ((String) object).equals("TIMEOUT"))
{
//Here you can do something with the Runnable before it is gone
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)