2013-04-25 84 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

相关问题