2017-04-05 3 views
0

J'ai un service en arrière-plan qui contient plusieurs threads qui lisent et écrivent sur des sockets TCP. Mon application se bloque après que je ferme les douilles et arrête le service. Il y a une exception SocketException lancée et interceptée par mon code avant que le crash ne se produise. Je ne sais pas pourquoi le SocketExeption provoque l'écrasement de mon application quand il a déjà été intercepté. Mais ce problème se produit uniquement dans l'un de mes téléphones fonctionnant sur Android 4.2. Aucun accident se produit sur android 5 ou andoird 6 jusqu'à présent.L'application se bloque après avoir fermé le socket en attente de lecture dans un thread

est Ci-dessous une partie du code:

public void logout() throws IOException { 
this.userName = ""; 
listenerService.p_status=false; 
listenerService.p_Thread.interrupt(); 
listenerService.c_status=false; 
listenerService.c_Thread.interrupt(); 
listenerService.closeSocket(); 
unbindService(mConnection); 
listenerService.stopService(); 

}

Voici les informations de débogage:

04-05 17:36:49.635 28101-28691/com.androidapp.ptt I/System.out: SOCKET CLOSED! 
04-05 17:36:49.635 28101-28691/com.androidapp.ptt W/System.err: java.net.SocketException: Socket closed 
04-05 17:36:49.635 28101-28691/com.androidapp.ptt W/System.err:  at libcore.io.Posix.recvfromBytes(Native Method) 
04-05 17:36:49.635 28101-28691/com.androidapp.ptt W/System.err:  at libcore.io.Posix.recvfrom(Posix.java:142) 
04-05 17:36:49.640 28101-28699/com.androidapp.ptt I/System.out: 404:kukukukukukuku 
04-05 17:36:49.640 28101-28691/com.androidapp.ptt W/System.err:  at libcore.io.BlockGuardOs.recvfrom(BlockGuardOs.java:164) 
04-05 17:36:49.640 28101-28691/com.androidapp.ptt W/System.err:  at libcore.io.IoBridge.recvfrom(IoBridge.java:499) 
04-05 17:36:49.640 28101-28691/com.androidapp.ptt W/System.err:  at java.net.PlainSocketImpl.read(PlainSocketImpl.java:488) 
04-05 17:36:49.640 28101-28691/com.androidapp.ptt W/System.err:  at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:46) 
04-05 17:36:49.645 28101-28691/com.androidapp.ptt W/System.err:  at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:240) 
04-05 17:36:49.645 28101-28691/com.androidapp.ptt W/System.err:  at java.io.InputStream.read(InputStream.java:162) 
04-05 17:36:49.645 28101-28691/com.androidapp.ptt W/System.err:  at com.androidapp.ptt.ListenerService$2.run(ListenerService.java:439) 
04-05 17:36:49.645 28101-28691/com.androidapp.ptt W/System.err:  at java.lang.Thread.run(Thread.java:841) 
04-05 17:36:49.685 28101-28101/com.androidapp.ptt I/System.out: Service done! 

Toute aide est très appréciée!

+0

Afficher stacktrace (il existe plusieurs options pour obtenir SocketException) et afficher plus de code. Probablement vous n'avez pas fermer le flux d'entrée/sortie ou quelque chose – DEADMC

+0

Maintenant, j'ai ajouté l'information de débogage à la question. Je viens de fermer le socket, pas explicitement éteindre l'inputtream et outputtream. Mais je pense que le flux d'entrée et de sortie doit être fermé automatiquement après la fermeture du socket.Le crash se produit uniquement dans Android 4.2, pas de problème avec Android 5.0 ou 6.0. – user1870797

+0

essayez de vérifier si la prise est déjà fermée ou non avant de la fermer(). – DEADMC

Répondre

1

Le thread qui a été bloqué dans read() a généré un IOException. C'est exactement le comportement qui devrait être attendu. Vous avez fermé la prise: elle est fermée. Vous ne pouvez pas continuer à lire.

Si vous souhaitez mettre fin à ce thread de manière agréable, appelez le shutdownInput() sur le socket au lieu de le fermer. Cela entraînera le déblocage du thread de lecture, la perception de la fin du flux et, si la réponse est correcte, l'arrêt de la lecture et la fermeture du socket.

+0

Merci, votre explication aide beaucoup. Il est préférable de débloquer le read() par shutdownInput() plutôt que de lancer une exception. Et mon code n'a pas correctement arrêté le fil et ferme le socket. Aussi, j'ai trouvé une chose intéressante: appeler Exception.printStackTrace() pourrait provoquer des exceptions non interceptées peut-être à cause de l'ordre d'exécution inattendu de plusieurs threads. Excetpion.printStackTrace() peut être appelé après que le service contenant ces threads a été terminé par un autre thread, puis entraîner le plantage de l'application. – user1870797