代码之家  ›  专栏  ›  技术社区  ›  JRowan

即使应用程序被销毁,AsyncTask也将始终运行?

  •  19
  • JRowan  · 技术社区  · 13 年前

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

    1. 异步任务 始终完成 doInBackground() onPostExecute() 即使应用程序关闭了 执行() 在应用程序运行时被调用?
    5 回复  |  直到 10 年前
        1
  •  15
  •   Community Mohan Dere    9 年前

    您将能够对此进行测试。是的,确实如此。如果调用了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">
    //....
    
        2
  •  9
  •   ddmps    10 年前

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

    简言之,你不能假设它会继续,也绝对不能认为它会发布进度或呼叫 onPostExecute()上 .

        3
  •  6
  •   Ashok Bijoy Debnath    11 年前

    当您对“活动”调用finish()时,“活动”会被销毁,但主线程不会。[注意:活动在主线程上运行。活动不是主线程。]

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

    **只有当进程是活动的,这些才是可能的;没有被Android低内存杀手杀死。

        4
  •  1
  •   Arun    8 年前

    请参阅图片,查看哪些方法在哪个线程中执行。

    enter image description here

        5
  •  1
  •   Alexandar    7 年前

    你可以很容易地测试这个,只需制作 doInBackground() 持续时间更长,例如添加 Thread.sleep(5000) 然后尝试各种场景:

    • 如果您完成了启动AsyncTask的“活动”,或者导航离开它,AsyncTask会正常完成,但随后可能会导致内存泄漏或应用程序在中崩溃 onPostExecute() 如果您持有对周围“活动”的引用(如UI元素),则该引用不再是“活动”。
    • 如果你按下“主页”按钮最小化你的应用程序,它将再次正常完成,但可能会使应用程序崩溃 onPostExecute()上
    • 如果你终止了你的应用程序进程(或者系统这样做),它将终止你的AsyncTask和你希望它做的工作 doIn背景() 不会这样做。如果您只是使用 new Thread(new Runnable() {...