Cancelar una conexión en curso cuando el usuario presiona de nuevo

He estado buscando sobre esto pero no encontré mi pregunta específica. Entiendo que AskyncTask se puede cancelar usando .cancel(true) pero esto sólo ocurre si tengo un bucle en el que puedo comprobar el valor isCanceled() .

Pero mi pregunta aquí es .. ¿cómo puedo cancelar un AsyncTask (que está atascado en httpclient.execute() ) cuando el usuario presiona de nuevo? Si el usuario navega lejos de esa actividad y va a otro no quiero tener un número incontrolado de AsyncTask en ejecución, ya que esto puede conducir a problemas de memoria, el usuario podría navegar hacia adelante y hacia atrás y crear un número indeterminado de tareas. Por eso quiero cerrarlos. Alguien sabe una manera? Puedo publicar el código que utilizo para conectarme:

 public class Test extends Activity { @Override protected void onStart() { super.onStart(); new ConnectionTask().execute("https://www.mywebserver.com/webservice.php?param1=test"); } private class ConnectionTask extends AsyncTask<String, Void, String>{ @Override protected String doInBackground(String... params) { try { HttpClient httpclient = DefaultHttpClient(params,clientConnectionManager); HttpPost httpPost = new HttpPost(params[0]); HttpResponse httpResponse = httpClient.execute(httpPost); HttpEntity httpEntity = httpResponse.getEntity(); if(httpEntity != null) return EntityUtils.toString(httpEntity); } catch (Exception e) { e.printStackTrace(); } return null; } } } 

¿Sabes lo que debo agregar en onStop () para cancelar la función httpClient.execute () en curso? A veces se queda atascado casi siempre.

Le agradecería mucho su ayuda, muchas gracias de antemano.

ACTUALIZAR

Si cierro el ConnectionManager tengo que hacer la ConnectionManager para https de nuevo, ¿verdad? Mira este código cuando creo el httpClient , uso esto para https:

 HttpClient httpclient = DefaultHttpClient(params,clientConnectionManager); 

Gracias a todos por sus respuestas rápidas y la variedad de soluciones expuestas aquí. Voy a tratar de usar los tiempos de espera (por no tener que esperar demasiado) + la función cancel() para evitar el procesamiento onPostExecute . Voy a decir si los resultados son como se esperaba! ¡Muchas gracias a todos!

Hay un método cancel() en la clase AsyncTask . Mantener un miembro asynctask y cancelarlo en onDestroy(). A continuación, establezca el miembro a null.

Actualizar

Utilice ClientConnectionManager para apagar la conexión.

http://developer.android.com/reference/org/apache/http/conn/ClientConnectionManager.html

Actualización 2

Compruebe este enlace para establecer el tiempo de espera para su conexión.

Cómo configurar el tiempo de espera de HttpResponse para Android en Java

De acuerdo con los documentos HttpClient , utilice HttpUriRequest#abort() para anular la solicitud

1.4. Abortar solicitudes

En algunas situaciones, la ejecución de la solicitud HTTP no se completa en el marco de tiempo esperado debido a la alta carga en el servidor de destino o demasiadas solicitudes concurrentes emitidas en el lado del cliente. En estos casos puede ser necesario terminar la solicitud de forma prematura y desbloquear el hilo de ejecución bloqueado en una operación de E / S. Las solicitudes HTTP que se ejecutan mediante HttpClient se pueden anular en cualquier etapa de ejecución invocando el método HttpUriRequest # abort (). Este método es thread-safe y se puede llamar desde cualquier subproceso. Cuando se aborta una petición HTTP, se garantiza que su subproceso de ejecución -incluso actualmente bloqueado en una operación de E / S- se desbloquee lanzando un comando InterruptedIOException

Mi comprensión es que httpClient.execute() está bloqueando, así que no hay código que funciona para comprobar el valor de isCancelled() . Y prefiere no cerrar el Connection Manager.

Esto podría ser un poco hacky, pero en lugar de cualquier mejor solución, ¿qué sucede si llama a Thread.interrupt() en el hilo mientras httpClient.execute() está bloqueando?

Una prueba rápida puede verificar esto, solo agregue una variable de instancia privada de tipo Thread dentro de la definición de ConnectionTask , Thread.currentThread() en Thread.currentThread() en la parte superior de doBackground() y agregue un método público que llame .interrupt() .

Si tienes suerte, hará que httpClient.execute() salga inmediatamente, lanzando una excepción. Usted puede coger eso y hacer cualquier tidup que necesita antes de la llamada al método termina y el AsyncTask termina naturalmente.

En onPause() o onBackButtonPressed() , llama a cancel() en tu tarea. En doInBackground() justo después

 HttpResponse httpResponse = httpClient.execute(httpPost); 

Compruebe isCanceled() e inmediatamente devuelva si es cierto.

Por supuesto, usted todavía tiene un riesgo de tener varias tareas en ejecución, pero ya que esta operación es UI impulsado (que es la tarea iniciada por las interacciones de los usuarios) debe haber en la mayoría de dos de ellos corriendo al mismo tiempo, siempre que el tiempo de espera en HttpClient es razonable.


Actualizar

También puede cerrar el administrador de conexiones una vez que determine que la tarea debe cancelarse. Ver documentos

Que debe cerrar los sockets y causar un retorno inmediato de execute() . El administrador de conexión se establece al crear DefaultHttpClient .

Puede anular

onPause() de la actividad y escriba allí el código de conexión de parada. Si la opción es específica para el botón Atrás, puede anular

onBackButtonPressed() para detener la ejecución.

Bueno, hay una solución rápida para este problema que solía resolver en mi caso. Puede que no sea la forma correcta, ya que al presionar de nuevo la aplicación responderá de inmediato, pero en el fondo la operación de red continuará (hasta el tiempo de espera si se establece) sin bloquear la aplicación:

Haga todo lo que la operación de la red en un nuevo servicio decir NSERV. Haga que el NSERV extienda la clase Thread y realice toda la operación de red en el método run. Para mayor claridad en su código, haga que la actividad / servicio que inicia el NSERV también extienda la clase Thread e inicie el NSERV desde su método run.

A continuación, utilice campos estáticos o singleton para acceder a las variables de la actividad / servicio de NSERV.

EX:

 public class NSERV extends Service implements Runnable{ public int onStartCommand (Intent intent, int flags, int startId) { Thread t = new Thread (this, "abc"); t.start(); return super.onStartCommand(intent, flags, startId); } public void run() { //NETWORK OPERATION... onDestroy(); } public void onDestroy() { stopSelf(); super.onDestroy(); } } 
  • Cómo cargar Android v7 soporte de la biblioteca en SBT Android Project?
  • Sockets, Threads y Servicios en android, ¿cómo hacerlos trabajar juntos?
  • No hay error aún Android Studio dice que "no se encontraron pruebas"
  • ¿Cómo administrar el montón nativo?
  • Android: mover los botones libremente en el editor de diseño gráfico de Eclipse
  • Cómo obtener mi hotspot wifi ssid en mi sistema android actual
  • Simple Xml - orden de elementos no conservados?
  • Problemas después de instalar java 8
  • Hace TimerTask ejecutando en nuevo hilo
  • ¿Copiar con el encargado del sujetapapeles que apoya versiones androides viejas y nuevas?
  • Determinar la existencia de la función Streetview de Google
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.