再次调用时如何重新启动异步方法?

How to restart async method when It's called again?

我对异步方法有疑问。每次调用它时都应该重新启动。如何实现?

在我的 Android 应用程序中,我想在仪表板上按月分组显示电影。电影存储在领域数据库中,一些用户在本地有很多电影,所以过程完成可能需要很多时间。这就是为什么我想在每次新组准备就绪时刷新 UI。问题是当领域数据库发生变化时(例如,当新电影从另一个服务到达时)我必须重新开始刷新过程。在新的刷新过程之前,必须停止前一个并且必须清除 UI。

UI:

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);
    //...
}
//...
}

视图模型:

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

在异步任务中,您可以覆盖onPreExcute() 和onPostExecute()。首先,创建像 isCurrentlyLoading 这样的布尔值并将其初始化为 false。然后在调用 loading

之前检查 isCurrentlyLoading 是否为 false
      @Override
    protected void onPreExecute() {
       isCurrentlyLoading = true;
    }

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