フラグメントをホストするアクティビティがあります。ボタンを押すと、FragmentTransactionを介してフラグメントAからフラグメントBに移動し、バックスタックに追加されます。これで、フラグメントBにAsyncTask実装が追加され、SDカードから画像が読み込まれ、画像が読み込まれるときに公開されます。[戻る]ボタンを押すと、アプリがクラッシュします。。エラーレポートは、戻るボタンが押されたときに非同期タスクがまだロードされていたため、非同期タスクが問題であることを示しています。したがって、私の質問は、戻るボタンが押されて前に戻るときにAsyncTaskを停止するにはどうすればよいですか。フラグメント/アクティビティ?..ありがとうございます。
5 に答える
フラグメントのonStop()をオーバーライドして、次のようにします。
protected void onStop() {
super.onStop();
//check the state of the task
if(task != null && task.getStatus() == Status.RUNNING)
task.cancel(true);
}
ホスティングアクティビティのonBackPressed()メソッドでこのコードを呼び出すだけです。同じことがonDestroy()を介したフラグメントにも当てはまります。
if(myFancyAsyncTask != null && myFancyAsyncTask.getStatus() == Status.RUNNING) {
myFancyAsyncTask.cancel(true);
}
これにより、実行中のAsyncTaskがキャンセルされます。ライフサイクルメソッドを使用してキャンセルされなかった場合は、必ずAsyncTaskを確認してください。
protected void onPostExecute(Long result) {
if(!isCancelled()) {
// do your work
}
}
将来の混乱を避けるために、このフラグメントのライフサイクルを確認することを強くお勧めします。そしてあなたの場合、asyncTaskをトップにするためにonPauseメソッドをオーバーライドする必要があると思います。
@Override
protected void onPause() {
super.onPause();
//check the state of the task
if(task != null && task.getStatus() == Status.RUNNING)
task.cancel(true);
}
onStop()でAsyncTaskをキャンセルすると、実行を継続したいシナリオでAsyncTaskが停止する可能性があるため、あまり適切な選択ではありません。ネットからダウンロードした複数の画像を表示し、画像をタップするとユーザーを別の画像固有のアプリに誘導するフラグメント/アクティビティがあるとします。これにより、フラグメントがonStop()にヒットし、ユーザーがアクティビティに戻ったときにダウンロードしたい画像がまだ残っている場合でも、AsyncTaskがキャンセルされます。onDestroy()でそれを行う方が良い選択だと思います。
@Override
public void onDestroy() {
super.onDestroy();
if(doTask != null){
doTask.cancel(true);
}
}
AsyncTaskRunner doAsynchronousTask; //Before onCreateView
//in onCreateView()
doAsynchronousTask = new AsyncTaskRunner();``
doAsynchronousTask.execute();
// after onCreateView()
@Override
public void onStop() {
super.onStop();
doAsynchronousTask.cancel(true);
}