¿Por qué el valor de tiempo de espera no es respetado por HttpURLConnection de Android?
Tengo el siguiente bloque de código:
try { URL url = new URL("http://site-to-test.com/nonexistingpage.html"); HttpURLConnection urlc = (HttpURLConnection) url.openConnection(); urlc.setRequestProperty("User-Agent", CoreProtocolPNames.USER_AGENT); urlc.setRequestProperty("Connection", "close"); urlc.setConnectTimeout(500); // timeout is in milliseconds urlc.connect(); if (urlc.getResponseCode() == 404) { // Server was reachable Log.i(TAG, "Server is reachable"); } } catch (MalformedURLException mue) { Log.e(TAG, "MalformedURLException: " + mue.getMessage()); } catch (IOException e) { Log.e(TAG, "IOException: " + e.getMessage()); }
Cuando el dominio site-to-test
no es accesible a través de la red actual, este código se bloquea durante aproximadamente 30-40 segundos antes de recibir la IOException
. Y establecí específicamente el valor del tiempo de espera a 500ms. ¿Que me estoy perdiendo aqui? ¿No debería terminar el bloque anterior en medio segundo, sin importar el estado de la red y la disponibilidad del sitio?
- Error al instalar debido a Tiempo de espera en Emulador
- ¿Qué es avg. Tiempo de conexión óptimo para aplicaciones móviles?
- Android - Envío de claves agotado
- Tiempo de espera para solicitud de servidor hecha usando "Volley" solo en Android no iOS
- Geolocalización de phonegap allways fail on timeout
- BroadcastReceiver onReceive timeout
- Error de aplicación en Emulator al iniciar debido a tiempo de espera
- ¿Por qué obtengo la excepción de tiempo de espera de pausa de actividad cuando mis datos son grandes?
- Archivo de httpclient para Android: corrupción de datos y problemas de tiempo de espera
- Error al instalar apk en el dispositivo 'emulator-5554': timeout
- Error de Android: No se pudo instalar * .apk en el dispositivo *: timeout
- Phonegap: Error de tiempo de espera llamando a webviewclient
- El tiempo de espera de conexión HTTP no funciona
Parece que Java URLConnection no proporciona ningún tiempo de espera a prueba de fallos en lecturas
Como se explica en el artículo, la solución es utilizar un hilo independiente para la temporización y desconectar la HttpURLConnection manualmente una vez que se realiza el hilo del temporizador.
Después de profundas investigaciones y un montón de pistas, encontré que la mejor manera de implementar un temporizador para AsyncTask (o Service, el objeto que utilizó para realizar trabajos de fondo) lejos de la clase de conexión HTTP, como a veces cuando desconecta la conexión HTTP, esto No interrumpe la llamada de la tela, implementé esta clase para ser utilizado cuando usted necesita la comprobación del tiempo de espera para su conexión del HTTP
public abstract class AsyncTaskWithTimer<Params, Progress, Result> extends AsyncTask<Params, Progress, Result> { private static final int HTTP_REQUEST_TIMEOUT = 30000; @Override protected Result doInBackground(Params... params) { createTimeoutListener(); return doInBackgroundImpl(params); } private void createTimeoutListener() { Thread timeout = new Thread() { public void run() { Looper.prepare(); final Handler handler = new Handler(); handler.postDelayed(new Runnable() { @Override public void run() { if (AsyncTaskWithTimer.this != null && AsyncTaskWithTimer.this.getStatus() != Status.FINISHED) AsyncTaskWithTimer.this.cancel(true); handler.removeCallbacks(this); Looper.myLooper().quit(); } }, HTTP_REQUEST_TIMEOUT); Looper.loop(); } }; timeout.start(); } abstract protected Result doInBackgroundImpl(Params... params); }
Una muestra para esto
public class AsyncTaskWithTimerSample extends AsyncTaskWithTimer<Void, Void, Void> { @Override protected void onCancelled(Void void) { Log.d(TAG, "Async Task onCancelled With Result"); super.onCancelled(result); } @Override protected void onCancelled() { Log.d(TAG, "Async Task onCancelled"); super.onCancelled(); } @Override protected Void doInBackgroundImpl(Void... params) { // Do background work return null; }; }