多个调用的MediatorLiveData观察器错误

时间:2018-10-07 17:09:45

标签: java android mvvm android-livedata

  • 如果登录为,我正在一个项目中下载一些文件 成功,然后打开“主要活动”。如果不是这样,则不会登录 也不下载文件并提示用户成功登录 下载所需的文件。
  • 失败后,如果用户输入正确的用户名和密码,则 它应该同时下载文件并打开“主要活动”。但是,在 在这种情况下,我的应用程序崩溃了。如果用户正确输入用户名和 初次尝试输入密码时,应用程序运行平稳。

  • 我有3个不同的LiveData对象,因此我可以借助MediatorLiveData观察所有对象,并根据情况调用下一个对象。错误输出:

  

E / Android运行时:致命异常:主要       工艺:com.cesar.sertificar,PID:7482        java.lang.IllegalArgumentException:此源已经与其他观察者一起添加           在android.arch.lifecycle.MediatorLiveData.addSource(MediatorLiveData.java:89)           在com.cesar.sertificar.ui.activity.login.LoginViewModel.handleFirstRunProcess(LoginViewModel.java:101)           在com.cesar.sertificar.ui.activity.login.LoginActivity.doLogin(LoginActivity.java:68)           在com.cesar.sertificar.ui.activity.login.LoginActivity.onClick(LoginActivity.java:88)           在android.view.View.performClick(View.java:5214)           在android.view.View $ PerformClick.run(View.java:20978)           在android.os.Handler.handleCallback(Handler.java:739)           在android.os.Handler.dispatchMessage(Handler.java:95)           在android.os.Looper.loop(Looper.java:145)           在android.app.ActivityThread.main(ActivityThread.java:6134)           在java.lang.reflect.Method.invoke(本机方法)           在java.lang.reflect.Method.invoke(Method.java:372)           在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:1399)           在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);
        });
    }

1 个答案:

答案 0 :(得分:0)

我在ViewModel中遇到了同样的问题。似乎这是MediatorLiveData的内部限制。如果看到添加了相同类型的LiveData,则它希望具有相同的侦听器来使用它。我将只添加我的案例,并添加相同的错误类型(无错误,可以正常工作)。 错误代码:

networkSum = new MediatorLiveData<>();
    networkSum.addSource(firstData, integer -> {
        if (integer == null) {
            firstIsFinished = false;
            errorInFirst = false;
        } else if (integer == SupportNetworkFunctions.STATUS_IN_PROGRESS) {
            networkSum.postValue(integer);
            firstIsFinished = false;
        } else if (integer == SupportNetworkFunctions.STATUS_FINISHED_WITH_ERROR) {
            firstIsFinished = true;
            errorInFirst = true;
            calculateFinished();
        } else {
            firstIsFinished = false;
            errorInFirst = false;
            calculateFinished();
        }
    });
    networkSum.addSource(secondData, integer -> {
        if (integer == null) {
            secondIsFinished = false;
            errorInSecond = false;
        } else if (integer == SupportNetworkFunctions.STATUS_IN_PROGRESS) {
            networkSum.postValue(integer);
            secondIsFinished = false;
        } else if (integer == SupportNetworkFunctions.STATUS_FINISHED_WITH_ERROR) {
            secondIsFinished = true;
            errorInSecond = true;
            calculateFinished();
        } else {
            secondIsFinished = false;
            errorInSecond = false;
            calculateFinished();
        }
    });

重构后:

networkSum = new MediatorLiveData<>();
    Observer<Integer> statusObserver = new Observer<Integer>() {
        @Override
        public void onChanged(@Nullable Integer integer) {
            if (integer != null) {

                if (integer == SupportNetworkFunctions.STATUS_IN_PROGRESS) {
                    networkSum.postValue(integer);
                } else if (integer == SupportNetworkFunctions.STATUS_FINISHED_WITH_ERROR) {
                    finishedItems++;
                    errorAppeared = true;
                    calculateFinished();
                } else {
                    finishedItems++;
                    calculateFinished();
                }
            }
        }
    };
    networkSum.addSource(firstData, statusObserver);
    networkSum.addSource(secondData, statusObserver);