2013-04-25 16 views
16

Ho un'applicazione e poiché non è possibile eseguire operazioni di rete sul thread principale sto utilizzando AsyncTask, quindi la domanda è una volta I execute() il AsyncTask e subito dopo l'attività finish() e forse l'utente sarà finish() intero app, quindi quello che mi chiedo è:AsyncTask verrà sempre eseguito anche se l'app viene distrutta?

  1. Will AsyncTask finire sempre doInBackground() e onPostExecute() anche se l'applicazione è chiusa finché execute() è stato chiamato quando l'applicazione è in esecuzione?
+4

Si dovrebbe usare la vostra attività del ciclo di vita per annullare l'esecuzione delle applicazioni, utilizzando il metodo 'cancel' di AsyncTask. È inutile continuare l'operazione di rete che probabilmente continuerà a funzionare anche se l'interfaccia utente è stata distrutta. Tuttavia, una volta completata l'operazione di rete, quando tenterà di aggiornare l'app dell'interfaccia utente, si verificherà un problema. – minhaz

risposta

13

Sarete in grado di testare questo. E sì, lo fa. Se è stato eseguito execute, è possibile vedere Asynctask verrà ancora eseguito SENZA ALCUNO fa qualcosa al forground o all'interfaccia utente. (potrebbe causare il blocco del programma di avvio).


Tuttavia, se era vicino al sistema. Può o non può continuare ad eseguire il metodo. Ho già testato e risposto allo here. Rispondi al commento: testati:

@Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     new Worker().execute(); 
    } 
private class Worker extends AsyncTask<Void, Void, String> { 

    @Override 
    protected String doInBackground(Void... arg0) { 
     Log.i("SomeTag", 
       "start do in background at " + System.currentTimeMillis()); 
     String data = null; 

     try { 
      DefaultHttpClient httpClient = new DefaultHttpClient(); 
      HttpGet httpGet = new HttpGet(
        "https://stackoverflow.com/questions/tagged/android"); 

      HttpResponse httpResponse = httpClient.execute(httpGet); 
      HttpEntity httpEntity = httpResponse.getEntity(); 
      data = EntityUtils.toString(httpEntity); 
      Log.i("SomeTag", 
        "doInBackGround done at " + System.currentTimeMillis()); 
     } catch (Exception e) { 
     } 
     return data; 
    } 

    @Override 
    protected void onPostExecute(String result) { 
     super.onPostExecute(result); 
     Log.i("SomeTag", System.currentTimeMillis()/1000L 
       + " post execute \n" + result); 
    } 
} 

@Override 
protected void onDestroy() { 
    super.onDestroy(); 
    Log.i("SomeTag", System.currentTimeMillis()/1000L + " onDestory()"); 
} 

04-24 21:42:57.981: I/SomeTag(5961): start do in background at 1366854177994 
04-24 21:43:00.974: I/SomeTag(5961): 1366854180 onDestory() 
04-24 21:43:02.946: I/SomeTag(5961): doInBackGround done at 1366854182946 
04-24 21:43:02.946: I/SomeTag(5961): 1366854182 post execute 
04-24 21:43:02.946: I/SomeTag(5961): <!DOCTYPE html> 
04-24 21:43:02.946: I/SomeTag(5961): <html> 
04-24 21:43:02.946: I/SomeTag(5961): <head> 
04-24 21:43:02.946: I/SomeTag(5961):   
04-24 21:43:02.946: I/SomeTag(5961):  <title>Newest &#39;android&#39; Questions - Stack Overflow</title> 
04-24 21:43:02.946: I/SomeTag(5961):  <link rel="shortcut icon" href="http://cdn.sstatic.net/stackoverflow/img/favicon.ico"> 
//.... 
+0

grazie è esattamente quello che stavo chiedendo, da quello che hai dichiarato devo andare e apportare alcune modifiche, cercando di farlo bene la prima volta che lo sai, grazie per il tuo tempo – JRowan

+0

Devo non essere d'accordo un po 'qui. AsyncTasks ** suppone ** che sia correlato all'interfaccia utente. 'OnPostExecute()' è ** sempre ** eseguito dal thread dell'interfaccia utente, quindi non verrà mai chiamato in quel caso. – ddmps

+0

@Pescis Aggiornato e testato. Per favore, fai notare il mio errore se trovi che il mio test è inaccurato. – wtsang02

8

onPostExecute() è chiamato dal thread UI - per cui se il thread dell'interfaccia utente non è in esecuzione, non continuerà a funzionare. Tuttavia, doInBackGround() viene eseguito da un thread di lavoro separato, quindi continuerà fino alla fine (o se il processo JVM viene ucciso dal sistema operativo, che è anche una possibilità). Tieni presente che i suggerimenti Async sono consigliati solo per le attività in background più limitate dell'interfaccia utente e non per il lavoro in background di lunga durata (alcuni secondi).

In breve, non si può presumere che continui e sicuramente non si presume che pubblicherà i suoi progressi o chiamare onPostExecute().

4

Quando si chiama finish() su Activity, l'attività viene distrutta, ma il thread principale non lo è. [NOTA: l'attività viene eseguita sulla discussione principale. L'attività non è Main Thread. ]

Quindi, doInBackground() sul thread in background e onPostExecute() sul thread principale verranno eseguiti. Tuttavia, se onPostExecute() esegue attività relative all'interfaccia utente, otterrai ANR perché non ci sono interfacce utente a questo punto. Ad esempio, se si stampa semplicemente un'istruzione Log.d() all'interno di onPostExecute(), l'istruzione sarà visibile in Logcat.

** Questi saranno possibili solo se il processo è attivo, & non viene ucciso da Android Low Memory Killer.

1

Vedere l'immagine per vedere quali metodi vengono eseguiti in quale thread.

enter image description here

Problemi correlati