再次调用时如何重新启动异步方法?
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;
}
我对异步方法有疑问。每次调用它时都应该重新启动。如何实现?
在我的 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;
}