응용 프로그램을 다시 시작하면 BindException이 발생합니다. 원격 제어 메시지를 기다리는 서버의 역할을합니다. ServerSocket은 백그라운드 스레드 (AsyncTask)에서 실행 중입니다. 내 응용 프로그램을 다시 시작한 후에는 항상 위에서 언급 한 예외가 발생합니다. 나는 그것을 듣기 위해 항구에 다시 묶을 때까지 10 분을 기다려야 만한다.응용 프로그램을 다시 시작한 후 "BindException : 주소가 이미 사용 중입니다"
내 포트를 차단하는 다른 응용 프로그램이 없으므로 다른 포트 (모두> 50000)를 사용해 보았습니다. 나는 소켓을 닫는 것에주의해야했고 SO_REUSEADDR 옵션을 사용하려고했다. 또한 나는 모든 socketbind를 기록했기 때문에 런타임에 하나의 연결 만 열려 있다고 확신합니다.
그래서 내가 생각하는 것은 연결이 제대로 닫히지 않는다는 것입니다. 나는 즉시 닫지 않는 소켓 습관에 대해 읽었습니다. 하지만 응용 프로그램을 다시 시작할 때마다 10 분을 기다릴 수 없어이 시간을 줄이거 나 종료 할 방법을 찾지 못했습니다.
의견이 있으십니까?
예외 :
10-04 16:39:22.526: WARN/System.err(4974): java.net.BindException: Address already in use
10-04 16:39:22.526: WARN/System.err(4974): at org.apache.harmony.luni.platform.OSNetworkSystem.bind(Native Method)
10-04 16:39:22.526: WARN/System.err(4974): at dalvik.system.BlockGuard$WrappedNetworkSystem.bind(BlockGuard.java:275)
10-04 16:39:22.526: WARN/System.err(4974): at org.apache.harmony.luni.net.PlainSocketImpl.bind(PlainSocketImpl.java:165)
10-04 16:39:22.526: WARN/System.err(4974): at java.net.ServerSocket.<init>(ServerSocket.java:123)
10-04 16:39:22.526: WARN/System.err(4974): at java.net.ServerSocket.<init>(ServerSocket.java:74)
10-04 16:39:22.526: WARN/System.err(4974): at com.*******.remote.RemoteHandlerListener$1.doInBackground(RemoteHandlerListener.java:114)
코드 :
ServerSocket server;
try {
server = new ServerSocket();
server.setReuseAddress(true);
server.bind(new InetSocketAddress(serverport));
} catch (IOException e) {
e.printStackTrace();
return null;
}
while (true) {
BufferedReader inStream = null;
Socket client = null;
try {
client = server.accept();
inStream = new BufferedReader(new InputStreamReader(client.getInputStream()));
// read from stream
} catch (Exception e) {
e.printStackTrace();
} finally {
if (inStream != null) {
try {
inStream.close();
} catch (IOException e) { }
}
if (client != null) {
try {
client.close();
} catch (IOException e) { }
}
}
}
try {
server.close();
} catch (IOException e) { }
예외는 server.bind 문에 발생합니다.
편집 : 문제의 원인 : accept-call이 차단되어 스레드가 종료되지 않습니다. 프로그램이 완전히 종료되지 않고 소켓이 언 바운드되지 않았습니다.
해결 방법 : 소켓에 SO_TIMEOUT을 설정하고 while() 루프에서 isCancelled를 확인하십시오. 이렇게하면 cancel()을 호출하면 스레드가 완료됩니다.
"restart"및 "background thread"를 정의 할 수 있습니까? 작업 관리자에서 응용 프로그램을 종료하고 다시 시작하거나 .apk를 다시 설치 하시겠습니까? 백그라운드 스레드를 말할 때 AsyncTask 또는 전통적인 Java 스레드를 사용하고 있으며 데몬으로 표시되어 있습니까? 이는 모두 응용 프로그램 수명주기와 VM이 동시성 단위와 함께 작동하는 방식과 관련이 있습니다. –
다시 시작한다는 것은 시작 작업에서 뒤로 버튼을 누른 다음 아이콘을 클릭하여 다시 시작한다는 것을 의미하므로 onDestroy 메서드를 호출하여 스레드를 중지합니다. taskmanager 또는 재설치가 필요하지 않습니다. taskmanager를 통해 응용 프로그램을 종료하면 문제가 해결되지만 실제 해결책은 아닙니다. –
배경 스레드로 AsyncTask를 사용합니다. –