Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Retrofit 2.0 cancel a Call object

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

like image 271
Etienne Lawlor Avatar asked Sep 16 '15 15:09

Etienne Lawlor


People also ask

What is call and callback in retrofit?

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 ).

What is call class in retrofit?

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.


1 Answers

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?

  • If not, you are safe to use onStop, as you've already described.
  • If so, you can move your network requests to a class that lives outside the 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:

  • Have all 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();
}
  • Set an 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.

like image 177
stkent Avatar answered Oct 20 '22 00:10

stkent