Как перезапустить асинхронный метод, когда он вызывается снова? - PullRequest
0 голосов
/ 28 октября 2018

У меня проблема с асинхронным методом.Каждый раз, когда он вызывается, он должен быть перезапущен.Как этого добиться?

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

Пользовательский интерфейс:

public class DashboardFragment extends BaseFragment {
//...
private DashboardViewModel viewModel;

private Observer<RealmResults<Movie>> movieObserver = movies -> {
    if (movies != null && movies.isLoaded())
        viewModel.refresh();
};

//...

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    //...
    viewModel.movies.observe(this, movieObserver);
    //...
}
//...
}

ViewModel:

public class DashboardViewModel extends AndroidViewModel {

    //..
    public RealmLiveDataResult<Movie> movies;

    //...
    public DashboardViewModel(@NonNull Application application) {
        super(application);

        //This provides a RealmLiveDataResult to have an observable to catch all the changes
        movies = new MoviesRepository().getMovies();
    }

    //...
    void refresh() {
        try (Realm realmDefault = Realm.getDefaultInstance()) {

            realmDefault.executeTransactionAsync(realmAsync -> {

                //If there are already rendered movies they should be cleared from the UI
                clearUI();

                //Find months contains movies
                RealmResults<Movie> moviesByMonth = realmDefault
                        .where(Movie.class)
                        .distinct("dateMonth")
                        .sort("date", Sort.DESCENDING);
                        .findAll();

                //Find movies by month
                for (Movie movieByMonth : moviesByMonth) {

                    //When this loop is still running but the refresh is called again it causes problems on the UI:
                    //It shows groups from the both processes
                    RealmQuery<Movie> allMoviesByMonthQuery = realmAsync
                            .where(Movie.class)
                            .equalTo("dateMonth", movieByMonth.getDateMonth())
                            .sort("date", Sort.DESCENDING);

                    List<Movie> moviesInTheMonth = realmAsync.copyFromRealm(allMoviesByMonthQuery.findAll());

                    //The new group is ready
                    showNewGroupOnUI(movieByMonth.getDate(), moviesInTheMonth);
                }
            });
        }
    }
}

1 Ответ

0 голосов
/ 28 октября 2018

В асинхронной задаче вы можете переопределить onPreExcute () и onPostExecute ().во-первых, создайте логическое значение типа isCurrentlyLoading и инициализируйте его как false.Затем проверьте, является ли isCurrentlyLoading ложным перед загрузкой вызова

      @Override
    protected void onPreExecute() {
       isCurrentlyLoading = true;
    }

    @Override
    protected void onPostExecute(String result) {
       isCurrentlyLoading = false; 
    }
...