I have a problem with an async method. Every time when its invoked It should be restarted. How to achieve that?
In my Android application, I want to show movies on the dashboard grouped by month. The movies are stored in a realm database and some users have a lot of movies locally, so it could be a bunch of time when the process finishes. That's why I want to refresh the UI every time when a new group is ready. The problem is when the realm database is changed (for example when new movies arrived from another service ) I have to start the refresh process again. Before the new refresh process, the previous one has to be stopped and the UI has to clear.
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);
//...
}
//...
}
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);
}
});
}
}
}
In Async task, you can override onPreExcute() and onPostExecute(). first, create boolean like isCurrentlyLoading and initialize it as false. Then check is this isCurrentlyLoading are false before call loading
@Override
protected void onPreExecute() {
isCurrentlyLoading = true;
}
@Override
protected void onPostExecute(String result) {
isCurrentlyLoading = false;
}