Как запланировать асинхронную задачу более контролируемым образом, чтобы сохранить использование сети - PullRequest
0 голосов
/ 19 апреля 2019

У меня есть асинхронная задача в одном из моих фрагментов.Всякий раз, когда фрагмент становится видимым, запускается асинхронная задача, и метод onPostExecute отображает данные после ее завершения.

Проблема в том, что каждый раз, когда фрагмент становится видимым, выполняется асинхронная задача, которая занимает 2 ~ 3 секунды, и каждый раз, когда отображается индикатор выполнения.Это раздражает.

Можно ли запланировать асинхронную задачу на

  1. , чтобы запускать ее только тогда, когда фрагмент виден в первый раз (каждый «первый раз», когда фрагмент виден после перезапуска приложения,не только при первой установке приложения)
  2. Через каждые 10 ~ 20 минут (или через определенный интервал времени) обновлять данные
  3. при нажатии кнопки обновления

Как сохранить использование сети от этой асинхронной задачи?

 protected void onPostExecute(String s) {
        super.onPostExecute(s);
            recyclerView.getItemAnimator().setChangeDuration(0);
            recyclerView.setNestedScrollingEnabled(false);
            recyclerView.setLayoutManager(new 
GridLayoutManager(getActivity(), mNoOfColumns));
            adapterDod = new AdapterDotd(getActivity(), data);
            adapterDod.notifyDataSetChanged();

            if (AsyncTaskCount == AsyncTaskRequested) {
                lottieAnimationView.setVisibility(View.GONE);
            }
            recyclerView.invalidate();
            recyclerView.setAdapter(adapterDod);
    }

Ответы [ 2 ]

0 голосов
/ 20 апреля 2019

Вы можете использовать компоненты архитектуры https://developer.android.com/topic/libraries/architecture И избавь себя от головных болей управления жизненным циклом. Особенно с использованием компонентов ViewModel и LifeData.

В виду модель

public class MyViewModel extends ViewModel {
  private MutableLiveData<List<Items>> itemsLiveData = new MutableLiveData();

    public void fetchDataFromNetwork() {
       .......
      startAsynWork()
    }

    .......
    onPostExecute(....) {
        itemsLiveData.setValue(data);
    }

    // Return a live data that will be observed in the fragment
    public LiveData<List<Items>> getItems() {
       return itemsLiveData;
    }

}

Затем во фрагменте

private MyViewModel viewModel;
onCreate(....) {
    viewModel = ViewModelProviders.of(this).get(MyViewModel.class);
    // Make network request here. It won't be repeated every time fragment is visible, only when it's created or recreated
    viewModel.fetchDataFromNetwork();
}

onCreateView(....) {

 .......
    viewModel.getItems().observe(this, items -> {
         updateUi(items)
    }
}
0 голосов
/ 19 апреля 2019

Прежде всего, вам необходимо записать и проверить время последнего обновления внутри onPostExecute.Сохраните его где-нибудь (переменная, SharedPreferences, DB и т. Д.)

Во-вторых, вам понадобится флаг, который записывает, если данный фрагмент был показан пользователю один раз, после запуска приложения.

После этого, если я правильно понял ваше намерение, добавьте хук к фрагменту, чтобы определить, является ли фрагмент видимым, если он виден и виден в первый раз, проверьте свою последнюю обновленную метку времени.Если время прошло достаточно хорошо, запустите эту асинхронную задачу.

Добавьте на кнопку отдельного прослушивателя событий, чтобы вручную запускать асинхронную задачу при нажатии кнопки.

Если вы также хотитеВыполняйте асинхронную задачу каждый раз, когда достигается определенное время (текущее и последнее обновленное), создайте задание таймера, которое выполняется в фоновом режиме, чтобы оно регулярно проверяло отметку времени последнего обновления и проверяло, достигнуто ли различие времениожидаемое количество, вызвать асинхронную задачу, если true.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...