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.

¿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.

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; } 
  • Mensajes de error NetlinkListener y NetlinkEvent
  • Android socket de programación ... ¿qué da?
  • ¿Cómo puedo manejar múltiples clientes conectados a un servidor mediante sockets?
  • ¿El zócalo del cliente androide, cómo leer datos?
  • Aplicación de chat: qué tecnología es mejor para implementar aplicación de chat en Android
  • Cliente-Servidor: Transferencia de archivos de Android a PC conectada vía socket
  • UDP Multicasting desde el móvil a la PC
  • Cuál es la mejor aproximación para enviar grandes paquetes UDP en secuencia
  • Android - Socket del servidor
  • Cómo enviar el archivo binario y el texto usando el mismo socket
  • Cómo resolver java.net.BindException: error de enlace: EADDRINUSE (Dirección ya en uso)
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.