【问题标题】:How to restart async method when It's called again?再次调用时如何重新启动异步方法?
【发布时间】:2019-04-01 11:44:41
【问题描述】:

我对异步方法有疑问。每次调用它时都应该重新启动它。如何做到这一点?

在我的 Android 应用程序中,我想在仪表板上按月份分组显示电影。电影存储在领域数据库中,一些用户在本地有很多电影,因此该过程完成可能需要很长时间。这就是为什么我想在每次准备好新组时刷新 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);
                }
            });
        }
    }
}

【问题讨论】:

  • 嗨,使用 volley developer.android.com/training/volley like library 来处理调用。它将管理你提到的那个场景
  • 我不确定 Volley 库如何帮助我。你能提供更多细节吗?也许这就是我的问题的答案。
  • 据我所知,它是针对 http 请求的。对于那件事我没有任何疑问。我在以异步方式刷新 UI 时遇到问题。
  • 抱歉。你怎么知道 prv refresh 完成了?有什么方法可以覆盖,比如 onComplet() 或 onFinish() ??
  • 没有办法。如果完成了 moviesByMonth 列表的循环,则该方法完成。我认为我应该为此创建一个 Refresher 类并为其使用标志,但我正在寻找一种很好且聪明的方法来做到这一点。

标签: java android asynchronous realm refresh


【解决方案1】:

在异步任务中,您可以覆盖 onPreExcute() 和 onPostExecute()。首先,创建类似 isCurrentlyLoading 的布尔值并将其初始化为 false。然后在调用加载之前检查 isCurrentlyLoading 是否为假

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

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

【讨论】:

  • 不错的一个!我会尝试一下,然后返回结果!我完全忘记了 asynctask 类。
猜你喜欢
  • 2016-09-29
  • 2016-01-14
  • 1970-01-01
  • 1970-01-01
  • 2020-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多