Reputation: 5458
In my fragment I have 2 AsyncTasks continuously running. The requirement is that when the user switches to a different frame using the Drawer menu, these tasks should be cancelled. However when the user presses the home button, these tasks should keep running.
I used the following code in that fragment:
@Override
public void onStop() {
super.onStop();
if(asyncTripWaiter != null && asyncTripWaiter.getStatus() == AsyncTask.Status.RUNNING)
asyncTripWaiter.cancel(true);
if(asyncTripTracker != null && asyncTripTracker.getStatus() == AsyncTask.Status.RUNNING)
asyncTripTracker.cancel(true);
}
The problem is that this piece of code executes even when the home button is pressed. How can I make it effective only when the fragment is switched.
Upvotes: 1
Views: 1391
Reputation: 415
It's not so simple,
please consider the situation when your fragment is going to back stack, then you can reach methods onPause()
and onStop()
.
User can either come back to this fragment in a second when AsyncTask
is still running.
Then it could be not really efficient to call AsyncTask
once again.
There is actually two options,
first one is the Syncing architecture solution when you're syncing your model separately from visible fragments, then you don't have to cancel AsyncTask
but it requires to change your application logic.
You can hear about it on
Android Application Architecture (Android Dev Summit 2015) As the lecturer said, it's not so important what kind of architecture you have, but it matters how you handle your data loading and caching.
So the first option is to cache the data separately from fragments and activities.
Second option is to keep your AsyncTask
alive but check is fragment the active one and/or cache the data even if it's not. User can go back to this fragment later.
This will not happen when fragment
is destroyed
so you can listen on onDestroy
method and set the flag like destroyed = true;
.
When AsyncTask
returns you can check
if (!destroyed) {
// do your job
}
Upvotes: 1
Reputation: 13390
Since you only need to cancel when you are switching, so 1 way of doing this would be to expose some public functions of the fragment
.
Switching of fragments most probably be happening in activity
, so before replacing, call that exposed function of fragment to cancel the asynctask.
e.g
In your fragment:
public void cancelAllTasks(){
// your logic to cancel tasks
}
In Activity:
yourFragment.cancelAllTasks();
...
replaceAnotherFragmentCode();
Upvotes: 0
Reputation: 1685
You can try it like this
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (!isVisibleToUser) {
if(asyncTripWaiter != null && asyncTripWaiter.getStatus() == AsyncTask.Status.RUNNING)
asyncTripWaiter.cancel(true);
if(asyncTripTracker != null && asyncTripTracker.getStatus() == AsyncTask.Status.RUNNING)
asyncTripTracker.cancel(true);
}
}
setUserVisibleHint() is a override method of fragment class.
Upvotes: 0