2013-04-25 13 views
16

Mam aplikacji i dlatego nie można zrobić operacji sieciowych w głównym wątku używam AsyncTask, więc pytanie jest raz execute()AsyncTask i zaraz potem ja finish() aktywności, a może użytkownik będzie finish() cała aplikacja, więc zastanawiam się, co jest:AsyncTask zawsze będzie działał, nawet jeśli aplikacja zostanie zniszczona?

  1. Will AsyncTask zawsze zakończyć doInBackground() i onPostExecute() nawet jeśli aplikacja jest zamknięty tak długo jak execute() nazwano gdy aplikacja została uruchomiona?
+4

Należy używać swoją aktywność cyklu życia, aby anulować uruchomione zadania, stosując metodę 'cancel' z Asynctask. Nie ma sensu kontynuować pracy w sieci, która najprawdopodobniej nadal będzie działać, nawet jeśli twój interfejs użytkownika zostanie zniszczony. Jednak po zakończeniu działania sieci, gdy będzie próbował zaktualizować aplikację UI, pojawi się problem. – minhaz

Odpowiedz

13

Będzie można przetestować to. I tak, tak. Jeśli wywołano execute, widać, że Asynctask będzie nadal wykonywany, O ile nie zrobi czegoś na forground lub interfejsie użytkownika. (może to spowodować awarię programu uruchamiającego).


Jednak, jeśli był blisko systemu. Może lub nie może kontynuować wykonywania metody. Przetestowałem i odpowiedziałem here. Odpowiedź: Testowany:

@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

dziękuje, że dokładnie to, co zastanawiałem się, od tego, co stwierdziliście, że muszę iść i dokonać pewnych zmian, próbując zrobić to dobrze za pierwszym razem, wiesz, dzięki za twój czas – JRowan

+0

Muszę się tu nieco nie zgodzić. AsyncTasks ** przypuszczalnie ** są powiązane z interfejsem użytkownika. Metoda 'onPostExecute()' jest ** zawsze ** uruchamiana z wątku interfejsu użytkownika, więc nigdy nie zostanie wywołana w tym przypadku. – ddmps

+0

@Pescis Zaktualizowano i przetestowano. Proszę wskazać mój błąd, jeśli uznasz mój test za nieścisły. – wtsang02

8

onPostExecute() jest wywoływana z wątku UI - więc jeśli wątek UI już nie pracuje, to nie będą działać. Jednak doInBackGround() jest uruchamiany z osobnego wątku roboczego, więc będzie działał aż do wykonania (lub jeśli proces JVM zostanie zabity przez system operacyjny, co również jest możliwe). Zauważ, że AsyncTasks są zalecane tylko dla krótszych zadań związanych z tłem, a nie długotrwałych prac w tle (kilka sekund).

Podsumowując, nie można zakładać, że będzie on trwał i zdecydowanie nie założy, że opublikuje swój postęp lub zadzwoni pod numer onPostExecute().

4

Po wywołaniu metody finish() w działaniu aktywność zostaje zniszczona, ale główny wątek nie jest aktywny. [UWAGA: Aktywność działa na głównym wątku. Aktywność nie jest głównym wątkiem. ]

Tak, doInBackground() na wątku tła i onPostExecute() na głównym wątku zostanie wykonany. Jeśli jednak onPostExecute() wykonuje dowolne zadania związane z interfejsem, otrzymasz ANR, ponieważ w tym momencie nie ma interfejsu użytkownika. Na przykład, jeśli po prostu wydrukujesz instrukcję Log.d() w instrukcji onPostExecute(), instrukcja będzie widoczna w Logcat.

** Będą one możliwe tylko w przypadku, gdy proces jest żywy, & nie zostanie zabity przez Androida Low Memory Killer.

1

Zobacz obraz, aby zobaczyć, jakie metody są wykonywane w którym wątku.

enter image description here

Powiązane problemy