即使应用程序被销毁,AsyncTask也会一直运行?

时间:2013-04-25 00:54:59

标签: android android-asynctask android-lifecycle

我有一个应用程序,因为你不能在我正在使用AsyncTask的主线程上进行网络操作,所以问题是我execute()AsyncTask及之后的问题我finish()这个活动,也许用户会finish()整个应用,所以我想知道的是:

  1. 只要在应用运行时调用了AsyncTask,应用就会关闭,doInBackground()总是会onPostExecute()execute()完成吗?

5 个答案:

答案 0 :(得分:14)

你将能够测试这个。是的确如此。如果调用了execute,你可以看到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">
//....

答案 1 :(得分:9)

从UI线程调用

onPostExecute() - 因此如果UI线程不再运行,它将不会继续运行。但是doInBackGround()是从一个单独的工作线程运行的,因此它将一直运行直到完成(或者如果JVM进程被操作系统杀死,这也是一种可能)。请注意,AsyncTasks仅建议用于较短的UI绑定后台任务,而不是长时间运行的后台工作(几秒钟)。

简而言之,您不能假设它会继续存在,并且绝对不会假设它会发布其进度或致电onPostExecute()

答案 2 :(得分:6)

当你在Activity上调用finish()时,Activity被销毁,但主线程却没有。 [注意:活动在主线程上运行。活动不是主线程。 ]

因此,将在后台线程上执行doInBackground()并在主线程上执行onPostExecute()。但是,如果onPostExecute()执行任何与UI相关的任务,您将获得ANR,因为此时没有UI。 例如,如果你只是在onPostExecute()中打印一个Log.d()语句,那么该语句将在Logcat中可见。

**只有当过程处于活动状态时,这些才有可能。没有被Android Low Memory Killer杀死。

答案 3 :(得分:1)

查看图片,了解哪个方法在哪个线程中执行。

enter image description here

答案 4 :(得分:1)

您可以轻松地进行测试,只需延长doInBackground()的使用时间即可,例如添加Thread.sleep(5000),然后尝试各种方案:

  • 如果您完成了启动AsyncTask的活动或从中退出,AsyncTask会正常完成,但是如果您持有对AsyncTask的引用,则可能会导致内存泄漏或使onPostExecute()中的应用崩溃周围的活动(如UI元素),不再“处于活动状态”。
  • 如果您通过按“主页”按钮将应用程序最小化,它将再次正常完成,但可能会在onPostExecute()中使应用程序崩溃
  • 如果您终止了应用程序进程(或系统执行了该进程),它将终止您的AsyncTask,并且您想要它执行的工作doInBackground()将不会完成。如果仅使用new Thread(new Runnable() {...
  • 启动线程,情况也是如此