У меня есть метод goToNextScreen()
, который выполняет проверку для 3 различных асинхронных процессов, поэтому, когда все процессы завершены, проверка изменит активность (является видом действия Splash)
Мой пример доступа к коду из3 различных результата обратного вызова метода действия goToNextScreen (), обновляющего значение флага для каждого процесса и проверяющего другие флаги внутри.
Пока этот подход работает, но у меня есть следующие вопросы:
Естьэтот подход действителен?Есть ли риск какого-то тупика?все потоки / обратные вызовы не будут сталкиваться при доступе к методу одновременно, вызывая неправильные проверки?
class LoadingActivity extends Activity{
public boolean isFetchDone, isAnimationDone, isServiceDone, watchDog;
Presenter presenter;
protected void onCreate(@Nullable Bundle savedInstanceState) {
presenter(this);
runAnimation();
presenter.runGetXService();
runFetchFromDB();
}
//do some generic isAnimationDone
private void runAnimation(){
//animator set and animation assumed to be correct...
//...
animatorSet.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
// do anything before animation start
}
@Override
public void onAnimationEnd(Animator animation) {
isAnimationDone = true;
goToNextScreen();
}
@Override
public void onAnimationCancel(Animator animation) {
// do something when animation is cancelled (by user/ developer)
}
@Override
public void onAnimationRepeat(Animator animation) {
// do something when animation is repeating
}
});
}
//Some example function to fetch data from x DB
private void runFetchFromDB() {
final Realm realm = RealmProvider.getInstance();
final ThingDB db = new ThingDBImpl(realm);
realm.beginTransaction();
db.getData(10L)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<XData>() {
@Override
public void onCompleted() {
isFetchDone = true;
goToNextScreen();
}
@Override
public void onError(Throwable e) {
//we dont care about the result
isFetchDone = true;
goToNextScreen();
}
@Override
public void onNext(XData dataSaved) {
//Should i update isFetchDone here?
});
realm.cancelTransaction();
}
private synchronized void goToNextScreen(){
if(!watchDog) return;
if(isFetchDone && isAnimationDone && isServiceDone){
changeActivityFaded(this, SomeOtherActivity);
finish();
watchDog = true;
}
}
}
class Presenter {
Activity activity;
Presenter(Activity activity){
this.activity = activity;
}
public void runGetXService(){
new Presenter.GetServiceAsyncTask().execute();
}
private class GetServiceAsyncTask extends AsyncTask<Void, Void, Response> {
@Override
protected void onPreExecute() {
super.onPreExecute();
//do preparation for service response, etc, asumme all correct
}
@Override
protected XResponse doInBackground(Void... voids) {
try {
return //Assume correct behaviour...
} catch (NetworkConnectionException e) {
return null;
}
}
@Override
protected void onPostExecute(XResponse xResponse) {
super.onPostExecute(xResponse);
((LoadingActivity)activity).isServiceDone = true;
((LoadingActivity)activity).goToNextScreen();
}
}
}
РЕДАКТИРОВАТЬ:
Я изменил метод goToNextScreen
synchronized
, поэтому он не должен разрешать доступ другим потокам одновременно.Все еще сомневаюсь, что с исполнением будет правильно.