¿Cómo ejecutar la misma asynctask más de una vez?

Tengo mi ejecución asyncTask cuando la actividad comienza por primera vez, y luego, si la conectividad de red no está disponible, entonces tengo un botón de actualización que intenta ejecutar la prueba asyncTask para volver a intentarlo. Pero recibo un error de depuración diciendo esto …

07-29 18:14:21.290: ERROR/AndroidRuntime(9080): FATAL EXCEPTION: main 07-29 18:14:21.290: ERROR/AndroidRuntime(9080): java.lang.IllegalStateException: Cannot execute task: the task has already been executed (a task can be executed only once) 07-29 18:14:21.290: ERROR/AndroidRuntime(9080): at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:541) 07-29 18:14:21.290: ERROR/AndroidRuntime(9080): at android.os.AsyncTask.execute(AsyncTask.java:499) 07-29 18:14:21.290: ERROR/AndroidRuntime(9080): at com.fttech.gameIT.MainMenu$1.onClick(MainMenu.java:90) 

¿Hay alguna forma de ejecutar esto dos veces?

Simplemente crea otra instancia y ejecútala.

Al igual que los hilos, AsyncTask s no puede reutilizarse. Debe crear una nueva instancia cada vez que quiera ejecutar una.

Nunca puede ejecutar un hilo de nuevo, no en Java , en ningún otro idioma, una vez que el hilo está terminado con el método run() , no puede reiniciarlo, y por eso está obteniendo IllegalStateException .

Sin embargo, puede llamar a los métodos en ese hilo, pero se ejecutarán en el hilo que los llama NO en un hilo diferente . Por lo tanto, deberás crear uno nuevo.

Simplemente realice una nueva llamada como new asyncTask (). Execute (); Debe crear un nuevo objeto para reiniciar esa tarea.

No puede ejecutar la misma instancia de una AsyncTask más de una vez. Supongamos que tiene una AsyncTask llamada MyAsyncTaks y tiene la intención de hacer algo como esto,

  MyAsyncTask myAsyncTask = new MyAsyncTaks(); myAsyncTask.execute(); // Works as expected . . . . myAsyncTask.execute(); // This will throw you exception 

La razón para esto es que, una vez que una secuencia termina su método de “ejecución”, no se le puede asignar otra tarea. Aquí, en la primera invocación de execute (), su AsyncTask comenzó a ejecutarse y después de hacer su trabajo, el hilo sale de ejecución. Naturalmente, la próxima invocación de execute () arrojará una excepción.

La forma más sencilla de ejecutar esto más de una vez es crear una nueva instancia de MyAsyncTaks y ejecutar ejecutar sobre eso.

  MyAsyncTask myAsyncTask = new MyAsyncTaks(); myAsyncTask.execute(); // Works as expected . . . MyAsyncTask myAsyncTask2 = new MyAsyncTaks(); myAsyncTask2.execute(); // Works as expected 

Aunque no es necesario mencionarlo aquí, hay que tener en cuenta que si publicas la versión Android SDK de Honeycomb, si ejecutas más de una AsyncTask a la vez, en realidad se ejecutan de forma secuencial. Si desea ejecutarlos de forma paralela, utilice executeOnExecutor en su lugar.

Simplemente creo la asynctask y luego creo un ejecutable que crea nuevas instancias de asynctask. Luego puede enviar su ejecutable una y otra vez al controlador.

 class MyAsyncTask extends AsyncTask{ ...} Runnable myRunner = new Runnable(){ public void run() { new MyAsyncTask ().execute(...); }}; myHandler.post(myRunner); 

Creé un Arraylist del tipo ProgressUpdater (nombre de la clase que extiende AsyncTask) y agregué las instancias en él (en el onClick de un botón). Entonces puede ejecutar y cancelar estas tareas cuando sea necesario.

 public class MainActivity extends Activity { ProgressBar progress; ProgressUpdater task; ArrayList pu = new ArrayList(); int count = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); progress = (ProgressBar) findViewById(R.id.progress); } public void onClick(View v) { switch (v.getId()) { case R.id.btn: task = new ProgressUpdater(); pu.add(task); count++; pu.get(count - 1).execute(0); System.out.println("task" + task); // task.execute(10); break; case R.id.btnCancel: if (count >= 0) { pu.get(count - 1).cancel(true); pu.remove(count - 1); count--; } // task.cancel(true); break; } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } private class ProgressUpdater extends AsyncTask { @Override protected void onPreExecute() { // TODO Auto-generated method stub super.onPreExecute(); progress = (ProgressBar) findViewById(R.id.progress); progress.setMax(100); } @Override protected Void doInBackground(Integer... params) { // TODO Auto-generated method stub int start = params[0]; for (int i = start; i <= 100; i++) { try { boolean cancelled = isCancelled(); if (!cancelled) { publishProgress(i); SystemClock.sleep(100); } } catch (Exception e) { e.printStackTrace(); } } return null; } @Override protected void onPostExecute(Void result) { // TODO Auto-generated method stub super.onPostExecute(result); Log.v("Progress", "Finished"); } @Override protected void onCancelled() { // TODO Auto-generated method stub super.onCancelled(); progress.setMax(0); } @Override protected void onProgressUpdate(Integer... values) { // TODO Auto-generated method stub super.onProgressUpdate(values); progress.setProgress(values[0]); } } 

}

en tu actividad principal puedes poner esto así:

 LeoAsyncTask leoAsyncTaskGeneric; public void onClick_AsyncTask(View view) { LeoAsyncTask leoAsyncTaskInner = new LeoAsyncTask(); leoAsyncTaskInner.execute(); leoAsyncTaskGeneric=leoAsyncTaskInner; 

}

/ ** si crea un espacio en la memoria de su clase AsyncTask como genérico, puede crear una instancia de esa misma clase dentro del método onClick, y allí los iguales, de modo que cada vez que presione onClick utilizará un nuevo instancia de Class AsyncTask, no le dará problemas * /

Podrías cancelar tu asyncTask cuando presionas el botón y luego lo ejecutas nuevamente.

Método OnClic interno:

 asyncTask.cancel(); AsyncTask asyncTask = new AsyncTask(); asyncTask.execute(); 

Enhebrar las reglas

  • La clase AsyncTask debe cargarse en el subproceso UI. Esto se hace automáticamente a partir de JELLY_BEAN.
  • La instancia de la tarea debe crearse en el hilo de la interfaz de usuario. execute (Params …) debe invocarse en el subproceso UI.
  • No invoque onPreExecute (), onPostExecute (Result), doInBackground (Params …), onProgressUpdate (Progress …) manualmente.
  • La tarea se puede ejecutar solo una vez (se lanzará una excepción si se intenta una segunda ejecución).

Para más detalles, consulte este enlace