Retrofit 2.0 отменить объект вызова

Кто-нибудь играл с Retrofit 2.0, в частности Call.cancel()?

Когда самое лучшее время для запуска этого? Я попробовал называть его onStop() Fragment, но столкнулся с некоторыми проблемами, когда вызов отменяется, когда экран отключается. Также я попробовал называть его onDestroy() Fragment, но этот метод не отменяет вызов, который запускается в ViewPager (например, переключение между вкладками)

Есть ли у кого-нибудь рабочий пример?

Я попытался реализовать это мое Loop repo: https://github.com/lawloretienne/Loop

Ответы

Ответ 1

"Правильное" место во многом будет зависеть от ваших конкретных случаев использования. Как вы обнаружили, вряд ли будет одноразовое решение. Вот несколько вещей, которые следует учитывать на основе ваших заявленных потребностей:


Является ли отменой сетевых запросов, когда экран выключен, большая проблема для вашего приложения? Может ли пользователь отключить экран, ожидая продолжения работы приложения?

  • Если нет, вы можете использовать onStop, как вы уже описали.
  • Если это так, вы можете переместить свои сетевые запросы в класс, который живет за пределами жизненных циклов Activity и Fragment (например, используя однопользовательский сетевой диспетчер запросов или больше полагается на подклассы Service). Затем вы сможете обрабатывать отмену в каждом конкретном случае. Например, вы все равно сможете отменить запросы в обратном вызове жизненного цикла всякий раз, когда захотите (указав это менеджеру), но вам не потребуется.

Что касается отмены сетевых запросов, вызванных Fragments в ViewPager, вы можете реализовать свои собственные методы faux-lifecycle. Здесь отличный образец, который я использовал пару раз. Суть заключается в следующем:

  • Все 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! Сообщите нам, что вы придумали.

Ответ 2

Попробуйте 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
        }
    }