2013-04-25 98 views
16

我有一個應用程序,因爲你不能做我使用AsyncTask在主線程網絡操作,所以問題是,一旦我​​的AsyncTask和之後,我finish()活動,也許用戶將finish()的整個應用程序,所以我想知道的是:即使應用程序被銷燬,AsyncTask也會一直運行?

  1. AsyncTask總是完成doInBackground()onPostExecute(),即使應用程序是隻要​​應用程序正在運行時,被稱爲關閉?
+4

你應該用你的活動生命週期取消正在運行的任務,使用'的AsyncTask的cancel'方法。繼續進行網絡操作是毫無用處的,即使您的用戶界面被破壞,最有可能繼續運行。但是在完成網絡操作後,它會嘗試更新您的UI應用程序時會遇到問題。 – minhaz 2013-04-25 01:10:29

回答

13

你將可以測試這個。是的,它的確如此。如果執行被調用,你可以看到Asynctask仍然會執行,除非它對於forground或UI相關。 (這可能會導致啓動器崩潰)。


但是,如果它靠近系統。它可能會也可能不會繼續執行該方法。我已經測試並回答了here。 回覆評論: 測試:

@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

感謝那正是我想知道的,從你說的我必須去做一些改變,試圖讓你第一次知道它是正確的,謝謝你的時間 – JRowan 2013-04-25 01:10:21

+0

我不得不在這裏有點不同意。 AsyncTasks是**假設**是與UI相關的。 'onPostExecute()'總是**從UI線程運行,所以在這種情況下永遠不會調用它。 – ddmps 2013-04-25 01:13:46

+0

@Pescis經過更新和測試。如果您發現我的測試不準確,請指出我的錯誤。 – wtsang02 2013-04-25 01:45:12

8

onPostExecute()從UI線程調用 - 所以,如果UI線程不再運行,它不會繼續運行。然而,doInBackGround()是從單獨的工作線程運行的,所以它會一直保持到完成狀態(或者JVM進程被OS終止,這也是一種可能性)。請注意,AsyncTasks僅建議用於較短的UI綁定後臺任務,而不是長時間運行的後臺工作(幾秒鐘)。

總之,你不能認爲它會繼續下去,絕對不能認爲它會公佈其進展或致電onPostExecute()

4

當您在Activity上調用finish()時,Activity被銷燬,但主線程不是。 [注意:活動在主線程上運行。活動不是主線程。 ]

因此,主線程上的後臺線程和onPostExecute()上的doInBackground()將被執行。但是,如果onPostExecute()執行任何與UI相關的任務,您將獲得ANR,因爲此時沒有UI。 例如,如果您只是在onPostExecute()內打印Log.d()語句,則該語句將在Logcat中可見。

**只有在進程存活的情況下,這些纔有可能,&未被Android Low Memory Killer殺死。

1

查看圖片,看看在哪個線程中執行哪些方法。

enter image description here

相關問題