2013-04-25 10 views
16

私は、アプリケーションを持っていて、私はAsyncTaskを使用しているメインスレッド上でネットワーク運用を行うことはできませんので、質問があるので、私は私が活動をfinish()、そしてAsyncTaskと右その後、多分、ユーザがfinish()ます​​たら全体のアプリは、そう私は思ったんだけどは次のとおりです。アプリが破棄されてもAsyncTaskは常に実行されますか?

  1. AsyncTask常にアプリがあれば、アプリが動作していたとき​​が呼ばれたように閉じていてもdoInBackground()onPostExecute()を終えるだろうか?
+4

あなたは 'Asynctaskのcancel'メソッドを使用して、タスクを実行しているキャンセルするあなたの活動のライフサイクルを使用する必要があります。あなたのUIが破壊されてもほとんど実行され続けるネットワーク操作を続行することは無意味です。しかし、ネットワーク操作の完了後に、あなたのUIアプリケーションを更新しようとすると、問題が発生します。 – minhaz

答えて

13

これをテストすることができます。はい、そうです。 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"> 
//.... 
+0

ありがとうthatsちょうど私が思っていたことは、私が行って、いくつかの変更を加えて、あなたが最初に知っていれば、あなたの時間のおかげでそれを取得しようとしていると述べたから – JRowan

+0

私は少しここに同意する必要があります。 AsyncTasksは** UI関連であると思われます**。 'onPostExecute()'はUIスレッドから**常に**実行されるので、その場合は決して呼び出されません。 – ddmps

+0

@Pescis更新され、テストされました。私のテストが不正確であると分かったら、私のエラーを指摘してください。 – wtsang02

8

onPostExecute()は、UIスレッドから呼び出される - ので、UIスレッドがもはや実行されている場合、それが実行し続けないではないでしょう: 検査済み: 返信はコメントします。しかし、doInBackGround()は独立したワーカースレッドから実行されるため、完了するまで(またはJVMプロセスがOSによって殺された場合は可能性があります)、継続されます。 AsyncTasksはUIバインドされたバックグラウンドタスクが短く、長時間実行されるバックグラウンドタスク(数秒)では推奨されません。

要するに、それが継続して進歩しているとは確信していないか、onPostExecute()に電話してください。

4

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

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

**これらは、プロセスが生きている場合にのみ可能です。&は、Androidロー・メモリー・キラーによって殺されません。

1

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

enter image description here

関連する問題