2016-05-26 13 views
1

AsynchTaskの中に私の活動は終了しましたdoinBackground()メソッドです。Android AsynchTaskの呼び出しアクティビティが完了している間に作業しています

postExecute()に達すると、UIの更新に使用されたアクティビティは既に破棄されていますが、TextViewはまだonPostExecute()でアクセス可能です。
これはどのように起こっているのかを説明できますか? AsyncTaskがキャンセルされた場合、新たな活動のコールを開始する前に

+0

アクティビティを終了したら、 'AsynchTask'(まだ実行中の場合)をキャンセルする必要があります。こちらをご覧くださいhttp://stackoverflow.com/a/7096045/5381331。 –

答えて

1

Androidの活動は、特定のライフサイクルを持っています。彼らが破棄ライフサイクル状態を過ぎると、はもはやAndroidで使用できなくなり、最終的にガベージコレクションされます。

しかし、アクティビティ参照またはその項目の任意のウィジェット参照をAsyncTaskに渡すと、GCによってアクティビティとその関連オブジェクト(ビューやウィジェットなど)のディスポジションが行われなくなります。さらに、独自の状態を持つ別のスレッドで実行されるAsyncTaskは、無効な1つまたは複数の参照オブジェクトを保持します。 AsyncTaskで参照を保持しているので、それらをGCで解放することはできません。

これは、アクティビティ参照でAsyncTasksを使用する際に非常に注意する必要がある理由です。また、UIを更新するためにAsyncTasksを使用することをやめてください。これを行う方法は他にもあります。

+1

これはこの質問に対する正確な正解です。 –

1

doInBackgroundメソッドチェックAsyncTask

asynTask.cancel(true) 

にし、あなたのasynctasksにキャンセルしたりしませ

@Override 
protected String doInBackground(String... urls) { 
    for(!isCancelled()) { 
     //do some stuff 
    } 
} 
0

質問には、どうなるかについての説明が必要です。 この単純なJavaコードを考えてみましょう。あなたがスレッドに渡す整数のインスタンスnはその値を保持しているため

public class myClass{ 
    public static void main(String[] args) { 
    int n=2; 
    MyThread t=new MyThread(n); 
    t.start(); 
    n=4; 
    System.out.println("n from main "+n); 
    } 
} 

class MyThread extends Thread{ 
    int n; 
    public MyThread(int n){ 
     this.n=n; 
    } 

    @Override 
    public void run(){ 
     try{ 
      Thread.sleep(2000); 
     }catch(Throwable e){ 
      System.out.println("error :"+e); 
     } 
     System.out.println("n from thread "+n); 
    } 
} 

と出力は次のようになり、

n from main 4 
n from thread 2 

は、これが起こります。これはAsyncTaskで起こるのと同じことです。この動作は、静的変数をnにして、新しいスレッド内でその静的変数への参照を行った場合に変更されます。

0

はあなたのactivityあなたactivityによるメモリをパージするように

  • システムなど、いくつかの理由で破壊され得ることができますすることは
  • は、あなたが電話を回転させる必要があります。その後Activityは殺され、あなたが明示的にあなたのロジックがAsyncTaskを実行するときに、このようなシナリオを処理する必要があるActivity

から戻ってナビゲート

  • を再現します。 ActivityAsyncTaskを開始すると、別のスレッドで実行され、終了したら結果をactivityに返します。 activityは、背景がAsyncTaskの場合、殺される可能性があります。あなたのactivityが殺される(onDestroy)と、AsyncTaskの結果を続行しない場合は、cancel(boolean)メソッドを呼び出すことをお勧めします。

  • 0

    AsyncTask(標準のJavaスレッドと同じ)は、ホストアクティビティのライフサイクルを考慮していません。適切なキャンセルを実装するのは開発者次第です(@mrDroidが示すように)。

    AsyncTaskLoaderを使用すると、アクティビティ構成の変更を処理するコードを記述する必要がなくなります。

    ホストアクティビティ(@George Metaxasのように)を直接参照しなくても、静的でない内部AsyncTaskは(内部クラスが外部クラスへの暗黙の参照を保持するため)メモリリークを引き起こす可能性があることに注意してください。

    関連する問題