2012-05-21 22 views
5

He probado la afirmación de que AsyncTasks no se destruyen junto con su actividad de lanzamiento. Y es verdadero.Android ¿Cómo volver a conectarse a AsyncTask después de onDestroy() y reiniciar onCreate()?

me hizo la AsyncTask acaba de publicar un mensaje Log.i() cada 3 segundos durante 1 minuto. Y pongo el mensaje Log.i() en el método onDestroy() de la actividad.

que ver la actividad se destruye, pero el AsyncTask mantiene en ejecución hasta que termine los 20 Log.i() mensajes.

Y estoy confundido.

  1. ¿Qué pasa si el AsyncTask tenía publishProgress() en la UI destruida?
    Supongo que se produciría algún tipo de excepción, ¿verdad?

  2. ¿Qué pasa si el AsyncTask almacena datos en una variable global de class Application?
    ¿No tienes idea aquí, excepción de NullPointer?

  3. ¿Qué pasa si se reinicia la aplicación?
    Probablemente lanzará una nueva AsyncTask. ¿Se puede volver a conectar con la aplicación AsyncTask que aún se está ejecutando?

  4. IS es destruido el inmortal AsyncTask después de la aplicación de la madre?
    Quizás sí, ¿cómo siguen todas las aplicaciones de LogCat registrando mensajes mientras la aplicación de interfaz de usuario ya no está visible, quizás destruida? Y cuando los vuelvas a abrir te muestran los mensajes que se generaron mientras estaba "muerto".

Todo esto parece una discusión, pero la pregunta está en el título. Tengo este AsyncTask huérfano, que me gustaría volver a conectar cuando la aplicación se relanza, pero no sé cómo hacerlo.

me olvidó decirle qué esto es muy importante. La aplicación se destruye cuando ocurre un cambio de orientación. Y no quiero perder los datos producidos por AsyncTask, no quiero detenerlo y reiniciarlo. Solo quiero que continúe y vuelva a conectar después de que se realicen los cambios de orientación.

Respuesta

1

Espero que tenga este derecho ya que es de un código anterior que ya no uso (ahora uso un IntentService para hacer lo que solía hacer).

Esto es lo que originalmente tenía cuando he descargado los archivos en mi principal ... Activity

public class MyMainActivity extends Activity { 

    FileDownloader fdl = null; 

    ... 

    // This is an inner class of my main Activity 
    private class FileDownloader extends AsyncTask<String, String, Boolean> { 
     private MyMainActivity parentActivity = null; 

     protected void setParentActivity(MyMainActivity parentActivity) { 
      this.parentActivity = parentActivity; 
     } 

     public FileDownloader(MyMainActivity parentActivity) { 
      this.parentActivity = parentActivity; 
     } 

     // Rest of normal AsyncTask methods here 

    } 
} 

La clave es usar onRetainNonConfigurationInstance() a 'salvar' el AsyncTask.

Override 
public Object onRetainNonConfigurationInstance() { 

    // If it exists then we MUST set the parent Activity to null 
    // before returning it as once the orientation re-creates the 
    // Activity, the original Context will be invalid 

    if (fdl != null) 
     fdl.setParentActivity(null); 
    return(fdl); 
} 

I a continuación, tienen un método llamado doDownload() que se llama a partir de onResume() si un Boolean indicando downloadComplete es cierto. El Boolean se establece en el método onPostExecute(...) de FileDownloader.

private void doDownload() { 
    // Retrieve the FileDownloader instance if previousy retained 
    fdl = (FileDownloader)getLastNonConfigurationInstance(); 

    // If it's not null, set the Context to use for progress updates and 
    // to manipulate any UI elements in onPostExecute(...) 
    if (fdl != null) 
     fdl.setParentActivity(this); 
    else { 
     // If we got here fdl is null so an instance hasn't been retained 
     String[] downloadFileList = this.getResources().getStringArray(R.array.full_download_file_list); 
     fdl = new FileDownloader(this); 
     fdl.execute(downloadFileList); 
    } 
} 
Cuestiones relacionadas