- I work on a project that downloads some files if the login is successful and then opens Main Activity. If not so, it neither logins nor downloads files and prompts the user to login successfully to download the required files.
After a failure, if a user writes correct username and password then it should both download files and open the Main Activity. However, in this case, my app crashes. If the user correctly writes username and password at first try, the app runs smoothly.
I have 3 different LiveData objects so that I can observe all of them with the help of
MediatorLiveData
and call the next one according to condition. The error output:
E/AndroidRuntime: FATAL EXCEPTION: main Process: com.cesar.sertificar, PID: 7482 java.lang.IllegalArgumentException: This source was already added with the different observer at android.arch.lifecycle.MediatorLiveData.addSource(MediatorLiveData.java:89) at com.cesar.sertificar.ui.activity.login.LoginViewModel.handleFirstRunProcess(LoginViewModel.java:101) at com.cesar.sertificar.ui.activity.login.LoginActivity.doLogin(LoginActivity.java:68) at com.cesar.sertificar.ui.activity.login.LoginActivity.onClick(LoginActivity.java:88) at android.view.View.performClick(View.java:5214) at android.view.View$PerformClick.run(View.java:20978) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:145) at android.app.ActivityThread.main(ActivityThread.java:6134) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
LoginViewModel.class
void handleFirstRunProcess() {
mIsNetworkAvailable.setValue(isAnActiveConnection());
mProcessResult.addSource(mIsNetworkAvailable, isNetworkAvailable -> {
mProcessResult.removeSource(mIsNetworkAvailable);
if (isNetworkAvailable == null) return;
if (!isNetworkAvailable) {
mProcessResult.setValue(new NetworkState(NetworkState.Status.FAILED,
getApplication().getString(R.string.first_run_network_warning)));
return;
}
doLogin(); //First doLogin
});
mProcessResult.addSource(mIsLoginSuccessful, isLoginSuccessful -> {
mProcessResult.removeSource(mIsLoginSuccessful);
if (isLoginSuccessful == null) return;
if (isLoginSuccessful.getStatus() == NetworkState.Status.FAILED) {
mProcessResult.setValue(new NetworkState(NetworkState.Status.FAILED,
getApplication().getString(R.string.login_error)));
return;
}
if (preferenceUtil.getBooleanData(Constants.FIRST_RUN_KEY, true)) {
downloadEmptyRecipientForm(); //Second download form if first run
} else {
mProcessResult.setValue(NetworkState.LOADED); //Open an activity
}
});
mProcessResult.addSource(mIsFormDownloadingSuccessful, isFormDownloaded -> {
mProcessResult.removeSource(mIsFormDownloadingSuccessful);
if (isFormDownloaded == null) {
return;
}
if (isFormDownloaded.getStatus() == NetworkState.Status.FAILED) {
mProcessResult.setValue(new NetworkState(NetworkState.Status.FAILED,
getApplication().getString(R.string.first_run_empty_form_error)));
return;
}
mProcessResult.setValue(NetworkState.LOADED); //Third open an activity
preferenceUtil.putBooleanData(Constants.FIRST_RUN_KEY, false);
});
}