AsyncTask всегда будет работать, даже если приложение будет уничтожено? - программирование
Подтвердить что ты не робот

AsyncTask всегда будет работать, даже если приложение будет уничтожено?

У меня есть приложение, и потому что вы не можете выполнять сетевые операции в основном потоке, я использую AsyncTask, поэтому вопрос один раз я execute() AsyncTask и сразу после этого я finish() и, возможно, пользователь будет finish() всем приложением, поэтому мне интересно:

  • Будет ли AsyncTask завершать doInBackground() и onPostExecute(), даже если приложение закрыто, если при запуске приложения вызывается execute()?
4b9b3361

Ответ 1

Вы сможете проверить это. И да, да. Если вызов был вызван, вы можете видеть, что Asynctask все равно будет выполняться, ЕСЛИ он что-то делает с привязкой к наземному или пользовательскому интерфейсу. (это может привести к сбою пусковой установки).


Однако, если он был близок к системе. Он может или не может продолжать выполнение метода. Я уже тестировал и ответил здесь. Ответить на комментарий: Проверено:

@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

onPostExecute() вызывается из потока пользовательского интерфейса, поэтому, если поток пользовательского интерфейса больше не работает, он не будет продолжать работать. Однако doInBackGround() запускается из отдельного рабочего потока, поэтому он будет продолжать работу до завершения (или если JVM-процесс будет убит ОС, что также возможно). Обратите внимание, что AsyncTasks рекомендуется только для более коротких фоновых задач с привязкой к UI, а не для работы на нескольких длинах фона (несколько секунд).

Короче говоря, вы не можете предположить, что он будет продолжать и определенно не предположить, что он опубликует свой прогресс или вызовет onPostExecute().

Ответ 3

Когда вы вызываете finish() в Activity, Activity уничтожается, но основной поток нет. [ПРИМЕЧАНИЕ. Активность работает в главной теме. Активность не является главной темой. ]

Итак, doInBackground() в фоновом потоке и onPostExecute() в основном потоке будет выполнен. Однако, если onPostExecute() выполняет какие-либо задачи, связанные с UI, вы получите ANR, потому что на данный момент нет пользовательского интерфейса. Например, если вы просто распечатываете оператор Log.d() внутри onPostExecute(), оператор будет виден в Logcat.

** Это будет возможно только в том случае, если процесс жив, и не убит Android Low Memory Killer.

Ответ 4

Посмотрите изображение, чтобы увидеть, какие методы выполняются в этом потоке.

введите описание изображения здесь