简体   繁体   中英

Stop AsyncTask in Fragments when Back Button is pressed

i have an activities that host fragments. pressing a button goes from fragment A to fragment B through a FragmentTransaction and the added to the back stack. Now fragment B has an AsyncTask implementation which loads images from an sdcard and publishes it as an image is loaded. if i press the Back button, my app crashes. . The error report indicates that the async task is the problem as it was still loading when the Back button was pressed, so my question is, how can i or where should i stop the AsyncTask when the Back button has been pressed to return to the previous fragment/activity?.. Thank you.

Override the onStop() of your fragment and do:

protected void onStop() {
    super.onStop();

    //check the state of the task
    if(task != null && task.getStatus() == Status.RUNNING)
        task.cancel(true);
}

Just call this code in the onBackPressed() -method of your hosting Activity - same applies to a Fragment via onDestroy() :

if(myFancyAsyncTask != null && myFancyAsyncTask.getStatus() == Status.RUNNING) {
  myFancyAsyncTask.cancel(true);
}

This will cancel a running AsyncTask for you. Be sure to check back in the AsyncTask if it was not cancelled by using the lifecycle-methods:

protected void onPostExecute(Long result) {
     if(!isCancelled()) {
       // do your work
     }
 }

I strongly recommend you to see this life cycle of fragment to avoid future confusions. And In your case I think you should override onPause method to top the asyncTask.

 @Override
protected void onPause() {
    super.onPause();
     //check the state of the task
    if(task != null && task.getStatus() == Status.RUNNING)
       task.cancel(true);
}

Canceling the AsyncTask in onStop() is not a very good choice because it can stop the AsyncTask in scenarios where you would want it to keep running. Imagine you have a fragment/activity where you show several images downloaded from the net and tapping an image is supposed to take the user to another image specific app. This would make your fragment hit onStop() and cancel your AsyncTask even though there may still be images you want to download for when the user comes back to the activity. I think doing it in onDestroy() is a better choice.

@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);
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM