Retrofit 2.0取消Call对象

时间:2015-09-16 15:23:30

标签: android api retrofit2 request-cancelling

有没有人玩Retrofit 2.0,特别是Call.cancel()方法?

什么时候触发它的最佳时机?我已经尝试在onStop()的{​​{1}}中调用它,但在屏幕显示关闭时遇到了一些问题,其中一个呼叫被取消了。我也尝试在Fragment的{​​{1}}中调用它,但此方法不会取消在onDestroy()中触发的调用(例如在标签之间切换)

有没有人有这方面的实例?

我试图实现这个我的循环回购: https://github.com/lawloretienne/Loop

2 个答案:

答案 0 :(得分:11)

“正确”的地方在很大程度上取决于您的具体用例。正如您所发现的那样,不可能有一个通用的解决方案。根据您的需求,可以考虑以下几点:

屏幕关闭时取消网络请求对您的应用来说是个大问题?用户是否可能在期望应用继续运行时关闭屏幕?

  • 如果没有,您可以安全地使用onStop,如您所述。
  • 如果是这样,您可以将网络请求移至位于ActivityFragment生命周期之外的类(例如,使用单一网络请求管理器,或更多地依赖Service子类)。然后,您将能够根据具体情况处理取消。例如,您仍然可以随时取消生命周期回调中的请求(通过向管理器发送信号),但您不会需要

关于取消FragmentsViewPager触发的网络请求,您可能希望实现自己的虚假生命周期方法。这是a great pattern I've used a couple of times。要点如下:

  • Fragments使用的所有ViewPager实现一个包含您关注的生命周期方法的“假”版本的接口。

示例:

public interface FragmentLifecycle {
    public void onStartFragment();
    public void onStopFragment();
}
  • OnPageChangeListener上设置ViewPager,并跟踪其中的当前页面。每当页面发生变化时,请调用传入/传出片段上的相应方法。

示例:

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

(我更新了链接示例以使用onStart / onStop,因为您已经在问题中提到了生命周期对。)

希望这能为您提供一些关于如何最好地使用Retrofit 2中的新取消功能的想法!让我们知道你的想法。

答案 1 :(得分:1)

您是否尝试 UserVisibleHint

   @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if (isVisibleToUser) {
                // fragment visible to user
        }else{
           // fragment invisible 
           // you can call Call.cancel() here
        }
    }