Entsperren von InputStream.read() auf Android?
Habe ich einen thread, in dem die read()
Methode eines InputStream
in einer Schleife aufgerufen wird. Wenn es keine bytes mehr gelesen, der stream wird blockiert, bis neue Daten eintreffen.
Wenn ich den Anruf close()
auf die InputStream
aus einem anderen thread, der stream geschlossen wird, aber die blockiert read()
nennen, bleibt immer noch gesperrt. Ich würde davon ausgehen, dass die read()
Methode sollte nun zurück, mit einem Wert von -1
an das Ende des Streams, muss es aber nicht. Stattdessen bleibt es blockiert mehrere Minuten, bis ein tcp-timeout Auftritt.
Wie entblocke ich den close()
nennen?
Edit:
Offenbar, die regelmäßige JRE werfen wird SocketException
sofort, wenn der Strom oder die Buchse blockieren read()
Anruf entspricht, ist close()
'd.... Die Android-Java-runtime, die ich benutze, jedoch nicht.
Irgendwelche Hinweise auf eine Lösung für die Android-Umgebung würde sehr geschätzt werden.
- Ich bin kein java-Typ, aber wenn Sie Steuern den app/thread senden den Strom hinab, konnte nicht senden Sie eine End-of-message-byte/paar bytes, die der Leser nutzen kann, um festzustellen, dass der stream geschlossen werden soll?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Nur anrufen
read()
wenn es Daten.Etwas zu tun:
legen Sie die
flagBlock
aufhören die zu Lesen.sleep
wie die Letzte Zeile der while-Schleife. Dies wird verhindern, dass Sie von busy waitingWenn das andere Ende schließt die Verbindung zum stream wird -1 zurück auf ein read(). Wenn Sie nicht auslösen, das andere Ende, um die Verbindung zu schließen, z.B. durch das schließen der output-stream, können Sie in der Nähe der Buchse, die bewirkt, dass eine IOException aus, in der die blockierende read () - thread.
Können Sie ein kurzes Beispiel, welches reproduziert dein problem?
Drucke
Sehen Java Concurrency In Practice für ein wirklich gutes system zum Abbrechen eines thread beim arbeiten mit sockets. Es verwendet eine spezielle executor (
CancellingExecutor
) und eine spezielle Callable (SocketUsingTask
).Wir hatten das gleiche Problem: keine Ausnahme, wenn switching-Netzwerk (z.B. Wechsel von 3G zu WiFi während des downloads).
Verwenden wir den code aus http://www.androidsnippets.com/download-an-http-file-to-sdcard-with-progress-notification, die funktioniert perfekt, außer in einigen Fällen, wenn die Netzwerkverbindung verloren wurde.
War die Lösung die Angabe eines timeout-Wert, wird dieser standard auf 0 (das bedeutet: warten unendlich).
Experiment mit einem timeout-Wert für Sie geeignet.
Könnten Sie
java.nio
Paket. NIO steht für Non-blocking IO. Hier der Anrufe (zu sagen, Lesen & schreiben) sind nicht blockiert. Auf diese Weise können Sie den stream schließen.Es ist ein Beispiel-Programm, das Sie anschauen können hier. Methode:
processRead
Hatte ich solche Problem auf Samsung 2.3. Beim Wechsel von 3G zu Wifi InputStream.read() Methode blockiert. Ich habe versucht, alle Tipps aus diesem Thema. Nichts half. Von meinem zukünftigen ist dieses Gerät spezifische Frage, weil es sollte werfen IOException aufgrund javadoc. Meine Lösung ist zu hören für android-broadcast android.net.conn.CONNECTIVITY_CHANGE und enge Verbindung aus einem anderen thread-es wird dazu führen, IOException im gesperrten thread.
Hier ist der code, Beispiel:
DownloadThread.java