Cómo desbloquear InputStream.read () en Android?
Tengo un hilo en el que el método read()
de un InputStream
se llama en un bucle. Cuando no hay más bytes para leer, el flujo se bloqueará hasta que lleguen nuevos datos.
Si llamo close()
en el InputStream
de un hilo diferente, el flujo se cierra, pero la llamada de read()
bloqueada sigue siendo bloqueada. Supongo que el método read()
debería volver ahora con un valor de -1
para indicar el final del flujo, pero no lo hace. En su lugar, permanece bloqueado durante varios minutos hasta que se produce un tiempo de espera tcp.
- Acceda a la impresora a través de Wifi desde el dispositivo Android
- La fuerza de aplicación se cierra al iniciar
- ¿Cómo ejecutar el servicio no en el hilo principal?
- Android: ¿Cómo detectar la aplicación eliminada de la lista de aplicaciones recientes?
- Pérdida severa de paquetes UDP en algunos dispositivos Android
¿Cómo desbloqueo la llamada close()
?
Editar:
Aparentemente, el JRE regular lanzará una SocketException
inmediatamente cuando la secuencia o el socket que la llamada de bloqueo read()
corresponde a close()
'd. El tiempo de ejecución de Java de Android que estoy usando, sin embargo, no lo hará.
Cualquier sugerencia sobre una solución para el entorno de Android sería muy apreciada.
- Conexión entre Python Server y la aplicación Android
- DatagramSocket.bind (); Socket excepción: no se puede asignar la dirección solicitada. Emulador de Android
- Sockets, Threads y Servicios en android, ¿cómo hacerlos trabajar juntos?
- Crear SSLSocket por SSLSocketFactory con tiempo de espera de conexión establecido
- ¿Cuál es el tiempo de espera predeterminado de java.net.Socket en android?
- Enviar datos a través de wifi (no internet) cuando los datos móviles
- Implementación cliente / servidor de socket TCP de Android
- ¿Hay algún mecanismo de devolución de llamada en android cuando hay datos disponibles para leer en socket
Sólo llama a read()
cuando hay datos disponibles.
Haz algo como eso:
while( flagBlock ) { if( stream.available() > 0 ) { stream.read( byteArray ); } }
flagBlock
el flagBlock
para detener la lectura.
Cuando el otro extremo cierra la conexión, su flujo retornará -1 en un read (). Si no puede disparar el otro extremo para cerrar la conexión, por ejemplo, cerrando el flujo de salida, puede cerrar el socket lo que causará una IOException en el bloqueo read () thread.
¿Puede proporcionar un breve ejemplo que reproduzca su problema?
ServerSocket ss = new ServerSocket(0); final Socket client = new Socket("localhost", ss.getLocalPort()); Socket server = ss.accept(); Thread t = new Thread(new Runnable() { public void run() { int ch; try { while ((ch = client.getInputStream().read()) != -1) System.out.println(ch); } catch (SocketException se) { System.out.println(se); } catch (IOException e) { e.printStackTrace(); } } }); t.start(); server.getOutputStream().write("hi\n".getBytes()); Thread.sleep(100); client.close(); t.join(); server.close(); ss.close();
huellas dactilares
104 105 10 java.net.SocketException: Socket closed
Vea Concurrency de Java en la práctica para un sistema realmente bueno para cancelar un hilo cuando se trabaja con sockets. Utiliza un ejecutor especial ( CancellingExecutor
) y un Callable especial ( SocketUsingTask
).
Estábamos teniendo el mismo problema: no hay excepción al cambiar de red (por ejemplo, cambiar de 3G a WiFi durante la descarga).
Estamos utilizando el código de http://www.androidsnippets.com/download-an-http-file-to-sdcard-with-progress-notification , que está funcionando perfectamente, excepto en algunos casos cuando se perdió la conexión de red.
La solución estaba especificando un valor de tiempo de espera, esto se establece en estándar a 0 (es decir: esperar infinitamente).
HttpURLConnection c = (HttpURLConnection) u.openConnection(); c.setRequestMethod("GET"); c.setDoOutput(true); c.setReadTimeout(1000); c.connect();
Experimente con un valor de tiempo de espera apropiado para usted.
Puede utilizar el paquete java.nio
. NIO significa No-bloqueo de E / S. Aquí las llamadas (para decir leer y escribir) no están bloqueadas. De esta manera puede cerrar el flujo.
Hay un programa de ejemplo que puede ver aquí . Método: processRead
Tuve tal problema en Samsung 2.3. Al cambiar de 3G a los bloques de método Wifi InputStream.read (). He intentado todos los consejos de este tema. Nada ayudó. Desde mi prospectivo este es un problema específico del dispositivo porque debe lanzar IOException debido a javadoc . Mi solución es escuchar android broadcast android.net.conn.CONNECTIVITY_CHANGE y cerrar la conexión de otro hilo que hará IOException en el hilo bloqueado.
Aquí está un ejemplo de código:
DescargarThread.java
private volatile boolean canceled; private volatile InputStream in; private boolean downloadFile(final File file, final URL url, long totalSize) { OutputStream out = null; try { Log.v(Common.TAG, "DownloadThread: downloading to " + file); in = (InputStream) url.getContent(); out = new FileOutputStream(file); return copy(out, totalSize); } catch (Exception e) { Log.e(Common.TAG, "DownloadThread: Exception while downloading. Returning false ", e); return false; } finally { closeStream(in); closeStream(out); } } public void cancelDownloading() { Log.e(Common.TAG, "DownloadThread: cancelDownloading "); canceled = true; closeStream(in); //on my device this is the only way to unblock thread } private boolean copy(final OutputStream out, long totalSize) throws IOException { final int BUFFER_LENGTH = 1024; final byte[] buffer = new byte[BUFFER_LENGTH]; long totalRead = 0; int progress = 0; int read; while (!canceled && (read = in.read(buffer)) != -1) { out.write(buffer, 0, read); totalRead += read; } return !canceled; }
- Establecer estilo en TableRow en Android
- Cómo cambiar el tamaño de la navegación ver los elementos del menú y el texto ?? ¿Cómo cambiar el espacio entre el menú?