Has anyone played around with Retrofit 2.0, specifically the Call.cancel() method?
When is the best time to trigger that? I have tried calling it in onStop()
of a Fragment
but have run into some issues with a call being cancelled when the screen display gets turned off. Also I tried calling it in onDestroy()
of a Fragment
but this method does not cancel a call that get triggered in a ViewPager
( for example switching between tabs)
Does anyone have a working example of this?
I have attempted to implement this my Loop repo : https://github.com/lawloretienne/Loop
The Call class is the starting point for every network request with Retrofit. Usually, you'll want to execute the request asynchronously with the enqueue method. The method expects a typed implementation of Retrofit's Callback class, which expects the implementation of two methods ( onResponse and onFailure ).
Think of Call as a simple class which wraps your API response and you need this class make an API call and provide listeners/callback to notify you with error and response , although if you use kotlin coroutines then after version 2.6.
The 'right' place will largely depend on your specific use-cases. As you've discovered, there's unlikely to be a one-size-fits-all solution. Here are a couple things to consider based on your stated needs:
Is cancellation of network requests when the screen is switched off a big problem for your app? Is a user likely to turn the screen off while expecting the app to continue functioning?
onStop
, as you've already described.Activity
and Fragment
lifecycles (e.g. using a singleton network request manager, or relying more on Service
subclasses). You will then be able to handle cancellations on a case-by-case basis. For example, you would still be able to cancel requests inside lifecycle callbacks whenever you wanted to (by signaling this to the manager), but you wouldn't be required to.With respect to cancelling network requests triggered by Fragments
in a ViewPager
, you might want to implement your own faux-lifecycle methods. Here's a great pattern I've used a couple of times. The gist is as follows:
Fragments
used by the ViewPager
implement an interface that contains 'fake' versions of the lifecycle methods you care about.Example:
public interface FragmentLifecycle {
public void onStartFragment();
public void onStopFragment();
}
OnPageChangeListener
on your ViewPager
, and track the current page inside it. Whenever the page changes, call the appropriate methods on the incoming/outgoing fragments.Example:
private OnPageChangeListener pageChangeListener = new OnPageChangeListener() {
int currentPosition = 0;
@Override
public void onPageSelected(int newPosition) {
final FragmentLifecycle fragmentToShow = (FragmentLifecycle) pageAdapter.getItem(newPosition);
fragmentToShow.onStartFragment();
final FragmentLifecycle fragmentToHide = (FragmentLifecycle)pageAdapter.getItem(currentPosition);
// Cancel network requests inside this callback. It
// corresponds to the current page moving off-screen.
fragmentToHide.onStopFragment();
currentPosition = newPosition;
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
// no-op
}
public void onPageScrollStateChanged(int arg0) {
// no-op
}
};
(I updated the linked example to use onStart
/onStop
since you already mentioned that lifecycle pair in your question.)
Hopefully that gives you some ideas as to how best to use the new cancellation features in Retrofit 2! Let us know what you come up with.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With