web-dev-qa-db-ja.com

アプリが破壊されても、AsyncTaskは常に実行されますか?

私はアプリケーションを持っていますが、メインスレッドでネットワーク操作を実行できないため、AsyncTaskを使用しています。そのため、問題はexecute()AsyncTaskで正しいことです。その後、私はアクティビティをfinish()し、おそらくユーザーはアプリ全体をfinish()するので、私が疑問に思っているのは次のとおりです。

  1. アプリの実行中にdoInBackground()が呼び出されている限り、アプリが閉じていても、AsyncTaskは常にonPostExecute()execute()を終了しますか?
17
JRowan

これをテストできるようになります。そしてそうです。 executeが呼び出された場合、フォアグラウンドまたはUI関連に何かを行わない限り、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">
//....
14
wtsang02

Activityでfinish()を呼び出すと、Activityは破棄されますが、メインスレッドは破棄されません。 [注:アクティビティはメインスレッドで実行されます。アクティビティはメインスレッドではありません。 ]

そのため、バックグラウンドスレッドのdoInBackground()とメインスレッドのonPostExecute()が実行されます。ただし、onPostExecute()がUI関連のタスクを実行する場合、この時点ではUIがないため、ANRが取得されます。たとえば、onPostExecute()内にLog.d()ステートメントを出力するだけの場合、ステートメントはLogcatに表示されます。

**これらは、プロセスが有効であり、Android Low MemoryKillerによって強制終了されない場合にのみ可能です。

6

画像を参照して、どのメソッドがどのスレッドで実行されるかを確認してください。

enter image description here

1
Arun

これは簡単にテストできます。たとえば、doInBackground()を長持ちさせるだけです。たとえば、Thread.sleep(5000)を追加して、さまざまなシナリオを試してください。

  • AsyncTaskを開始したアクティビティを終了するか、そこから移動すると、AsyncTaskは正常に終了しますが、周囲への参照を保持している場合は、メモリリークが発生するか、onPostExecute()でアプリがクラッシュする可能性があります。アクティビティ(UI要素など)。これはもう「生きて」いない。
  • 「ホーム」ボタンを押してアプリを最小化すると、アプリは再び正常に完了しますが、onPostExecute()でアプリがクラッシュする可能性があります
  • アプリプロセスを強制終了すると(またはシステムが強制終了すると)、AsyncTaskが終了し、実行したいジョブdoInBackground()は実行されません。 new Thread(new Runnable() {...を使用してスレッドを開始するだけでも同じことが言えます。
1
Alexandar