Android llama a AsyncTask justo después de que otro termine

Tengo algún problema con Android AsyncTask. Hay una actividad que contiene algunos TextView un botón y una imagen. Cuando un usuario entró en esta actividad, inicie un asynctask para verificar si el usuario puede ir hacia la actividad (hasta que la tarea no termine el botón no activo). Entonces quiero comenzar otra asyntax para obtener la imagen. Así que hice una clase interna:

AsyncTask<String, Void, JSONObject>() authTask = new AsyncTask<String, Void, JSONObject>() { @Override protected JSONObject doInBackground(String... params) { //call the rest api } @Override protected void onPostExecute(JSONObject result) { // check the result // and make another asynctask AsyncTask<String, Void, Bitmap> imageTask = new Async.... { // get image } imageTask.execute(); } } 

Y llamo authTask.execute(); Desde el subproceso de interfaz de usuario.

Tengo un mal presentimiento acerca de esto, especialmente parece que no funciona (está bien pocas veces, pero de repente "congelar": no hay excepción sólo colgando y la barra de progreso está girando.No pasa nada y el botón no estará activo.) Hay otra manera de obtener una información y cuando se ha terminado inmediatamente iniciar otra tarea?

UDPATE: Trabajo con api nivel 10. En authTask consigo cierta información que es necesaria para iniciar imageTask (algunos id) así que tengo que llamar a estas tareas en una fila. En api nivel 10 es posible?

¡Gracias por adelantado!

Hermano Peter

Puede utilizar getStatus() comprueba si el AsyncTask está pendiente, en ejecución o terminado. Y cuando finsh inicie su nueva task.like:

 if(authTask .getStatus() == AsyncTask.Status.PENDING){ // My AsyncTask has not started yet } if(authTask .getStatus() == AsyncTask.Status.RUNNING){ // My AsyncTask is currently doing work in doInBackground() } if(authTask .getStatus() == AsyncTask.Status.FINISHED){ // START NEW TASK HERE } 

Ejemplo para tu aplicación:

 btn.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { if (authTask != null && authTask.getStatus() == AsyncTask.Status.FINISHED) { //START YOUR NEW TASK HERE } else { //IGNORE BUTTON CLICK } } }); 

1

Usted podría escribir el código para authTask y luego para imageTask, uno tras otro, dentro de un solo doInBackground() . Esta única instancia AsyncTask sería activada por una sola sentencia execute() . Esto puede o no ser práctico dependiendo de las interacciones necesarias de la interfaz de usuario.


2

Editar: como se ha señalado por kabuku esta información es sobre todo para HoneyComb +. Pre HoneyComb Definitivamente iría con la opción 1 anterior. ExecuteOnExecutor () es api nivel 11+

En las versiones de receent, execute() enviará sus AsyncTasks en serie por defecto (ICS +). Si desea asegurarse de que esto suceda, especifique el ejecutor en serie.

En su caso esto sería:

 authTask.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR); // Image task will only be done AFTER textViewTask is done imageTask.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR); 

Y para las versiones más recientes un simple

 ... // ICS+ and pre honeycomb (I think) authTask.execute(); // Image task will only be done AFTER textViewTask is done imageTask.execute(); ... 

Desde la documentación de AsycnTask.execute ():

Nota: esta función programa la tarea en una cola para un solo subproceso de fondo o grupo de subprocesos dependiendo de la versión de la plataforma. Cuando se introdujo por primera vez, AsyncTasks se ejecutaron en serie en un solo hilo de fondo. Comenzando con DONUT, esto fue cambiado a un grupo de hilos permitiendo que múltiples tareas funcionaran en paralelo. Después de HONEYCOMB, se planea cambiar esto de nuevo a un solo hilo para evitar errores comunes de aplicación causados ​​por la ejecución paralela.


PS: Para ejecutar tareas independientes entre sí debe utilizar el AsyncTask.THREAD_POOL_EXECUTOR . Eso requiere un ejecutor diferente:

 // Go parallel! (NOT what you want) task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); 

No es un buen diseño para anidar AsyncTask. Hacer todo el trabajo pesado en doInBackground y simplemente publicar / actualizar los resultados. En otras palabras, combine el procesamiento de la segunda AsyncTask en su primera.

Desde el código que mostró que no parece tener sentido para generar segunda tarea. Sólo tienes que obtener la imagen dentro de doInBackground de la primera tarea después de la autorización. Si necesita actualizar la interfaz de usuario, puede hacerlo en progreso.

 int count; private void attemptConnect() { count = 0; str_lang = "English"; str_wait = "Plaese Wait"; new AllQuestion().execute(); } private class AllQuestion extends AsyncTask<String, String, String> { ProgressDialog pg; @Override protected void onPreExecute() { super.onPreExecute(); pg = new ProgressDialog(LanguageActivity.this); pg.setProgressStyle(ProgressDialog.STYLE_SPINNER); pg.setMessage(str_wait); pg.setCancelable(false); pg.show(); } @Override protected String doInBackground(String... strings) { try { SoapObject soapObject = new SoapObject(AppConstant.NAMESPACE, AppConstant.QUESTION_SOAP_METHOD); soapObject.addProperty("language", str_lang); SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); envelope.dotNet = true; envelope.setOutputSoapObject(soapObject); HttpTransportSE se = new HttpTransportSE(AppConstant.webUrl); se.call(AppConstant.QUESTION_SOAP_ACTION, envelope); Object responce = envelope.getResponse(); Log.d("Question List:=>>", "" + responce); return responce.toString(); } catch (Exception e) { e.printStackTrace(); pg.dismiss(); return null; } } @Override protected void onPostExecute(String s) { super.onPostExecute(s); if (pg.isShowing()) { pg.dismiss(); Log.i(TAG, s); if (s != null || !s.equalsIgnoreCase("")) { try { JSONArray array = new JSONArray(s); for (int i = 0; i < array.length(); i++) { JSONObject obj = array.getJSONObject(i); String queId = obj.getString(TAG_QID); String que = obj.getString(TAG_QUE); String str_Opt = obj.getString(TAG_OPT); question = new Question(queId, que, str_lang, str_catId, str_Opt, manager.getDateTime()); helper.insertQuestion(question); } count++; if (count < 5) { if (count == 1) { str_lang = "German"; str_wait = "bitte warte einen Moment"; new AllQuestion().execute(); } if (count == 2) { str_lang = "Italian"; str_wait = "per favore aspetta un momento"; new AllQuestion().execute(); } if (count == 3) { str_lang = "Chinese"; str_wait = "请稍候"; new AllQuestion().execute(); } if (count == 4) { str_lang = "French"; str_wait = "patientez s'il-vous-plait"; new AllQuestion().execute(); } Log.d("All Question:-", question.toString()); } catch (JSONException e) { e.printStackTrace(); } } } } } 

Tengo una idea para hacer series asíncronas en una sola tarea asíncrona :

 protected Boolean doInBackground(String... params) { if(params[0] == "taskA") { //do somthing params[0] = "taskB"; } if(params[0] == "taskB") { //do somthing params[0] = "taskC"; } if(params[0] == "taskC") { //do somthing params[0] = "taskD"; } if(params[0] == "taskD") { //do somthing return true; } 

Y en su hilo principal simplemente llame a una tarea asíncrona de la siguiente manera:

 ShowMyProgress(); //if you like new MyAsyncTask().execute("taskA"); 

Y finalmente puede ocultar su progreso en onPostExecute como:

 protected void onPostExecute(final Boolean success) { if (success) { .... HideMyProgress(); } } 
  • AsyncTask no se ejecuta asincrónicamente
  • Async tarea para mostrar un AlertDialog
  • Cómo utilizar AsyncTask en Servicios en Android?
  • AsyncTask: ¿dónde va el valor de retorno de doInBackground ()?
  • Problemas con las devoluciones de llamada personalizadas de AsyncTaskLoader
  • Servicio v / s AsyncTask
  • AsyncTask matar tarea al pulsar el botón de nuevo
  • Android runOnUiThread / AsyncTask no puede resolver CalledFromWrongThreadException
  • Cómo manejar AsyncTask onPostExecute cuando se pausan para evitar IllegalStateException
  • AsyncTask no llamando a onProgressUpdate, onPostExecute
  • Cómo utilizar AsyncTask correctamente
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.