J'ai reçu une exception BindException lorsque j'ai redémarré mon application. Il agit comme un serveur en attente de messages de contrôle à distance. ServerSocket est en cours d'exécution dans un thread d'arrière-plan (AsyncTask). Après le redémarrage de mon application, je reçois toujours l'exception mentionnée ci-dessus. Je dois attendre comme 10 minutes jusqu'à ce qu'il puisse se lier à nouveau au port afin d'écouter."BindException: adresse déjà utilisée" après le redémarrage de l'application
J'ai essayé différents ports (tous> 50000) donc je suis sûr qu'il n'y a pas d'autre application bloquant mon port. J'ai essayé de faire attention à la fermeture du socket et j'ai essayé d'utiliser l'option SO_REUSEADDR. Aussi je suis sûr qu'il n'y a qu'une seule connexion ouverte au moment de l'exécution, depuis que je me suis connecté chaque socketbind.
Donc ce que je pense est que la connexion n'est pas fermée correctement. J'ai lu à propos de l'habitude des prises qui ne se ferment pas instantanément. Mais je ne peux pas attendre 10 minutes à chaque redémarrage de l'application et je n'ai pas trouvé un moyen de raccourcir ou de tuer cette fois.
Avez-vous des idées?
L'exception:
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)
Le code:
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) { }
L'exception est levée sur la server.bind-déclaration.
EDIT: Cause du problème: Le thread ne se terminera pas automatiquement car l'appel accepté est bloqué. Le programme ne s'est pas terminé complètement et le socket n'était pas non lié.
Solution: Définissez SO_TIMEOUT sur le socket et recherchez isCancelled dans la boucle while(). De cette façon le thread finira si vous appelez cancel() dessus. Essayez d'imprimer la pile de toutes les exceptions interceptées.
Pouvez-vous définir «redémarrage» et «thread de fond»? Êtes-vous en train de tuer l'application du gestionnaire de tâches et de la redémarrer, ou simplement en réinstallant le .apk? Lorsque vous indiquez un thread d'arrière-plan, utilisez-vous un AsyncTask ou un thread Java traditionnel et il est marqué en tant que démon? Tous ces éléments sont pertinents pour la manière dont le cycle de vie de l'application et la machine virtuelle fonctionnent avec les unités de concurrence. –
En redémarrant je veux dire appuyer sur le bouton de retour dans l'activité de démarrage et ensuite le redémarrer en cliquant sur l'icône invoquant ainsi la méthode onDestroy où j'arrête le thread. Aucun gestionnaire de tâches ou réinstallation impliqué. Tuer l'application via taskmanager résout le problème mais n'est pas une vraie solution. –
En tant que thread d'arrière-plan, j'utilise une asyncTask. –