任何人都可以为我正确解释这个表达式......这似乎是我目前面临的问题。
Starts to listen the given source LiveData, onChanged observer will be called when source value was changed.
onChanged
callback will be called only when this MediatorLiveData is active.If the given LiveData is already added as a source but with a different Observer,
IllegalArgumentException
will be thrown.
我目前有以下作为我的 ViewModel(称为 SplashViewModel
)
package com.testapp.testapp.ui.splash;
import com.testapp.testapp.repository.HealthTipRepository;
import javax.inject.Inject;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MediatorLiveData;
import androidx.lifecycle.ViewModel;
public class SplashViewModel extends ViewModel {
private final HealthTipRepository healthTipRepository;
// Load Status will be used to fill up the progress bar inside the Activity
private final MediatorLiveData<Integer> loadStatus = new MediatorLiveData<>();
@Inject
SplashViewModel(HealthTipRepository healthTipRepository) {
this.healthTipRepository = healthTipRepository;
}
LiveData<Integer> observeLoadStatus() {
loadStatus.addSource(healthTipRepository.createHealthTips(), healthTips -> {
int currentValue = loadStatus.getValue();
int newValue = currentValue != null ? currentValue + 25 : 25;
loadStatus.setValue(newValue);
});
}
}
在 Activity 中,我有这个:
package com.testapp.testapp.ui.splash;
import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.LocationManager;
import android.os.Bundle;
import android.provider.Settings;
import android.view.View;
import android.widget.ProgressBar;
import com.testapp.testapp.R;
import com.testapp.testapp.storage.PrefManager;
import com.testapp.testapp.ui.BaseActivity;
import com.testapp.testapp.ui.FactoryViewModel;
import javax.inject.Inject;
import androidx.annotation.Nullable;
import androidx.lifecycle.ViewModelProviders;
import butterknife.BindView;
// Base Activity has already injected the Dagger component
public class SplashActivity extends BaseActivity {
@BindView(R.id.splash_progress)
ProgressBar progressBar;
@Inject
FactoryViewModel factoryViewModel;
private SplashViewModel viewModel;
// PrefManager is responsible for managing shared preferences. It exposes a .get Method
@Inject
PrefManager prefManager;
@Override
protected void onCreate(@Nullable Bundle savedInstance) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash_activity);
ButterKnife.bind(this);
viewModel = ViewModelProviders.of(this, factoryViewModel).get(SplashViewModel.class);
}
@Override
protected void onResume() {
super.onResume();
// Performs checks to turn on location. The viewmodel is placed in the
// onREsume to ensure that even when we leave the activity to turn on the
// location and return, we can always start the viewmodel
boolean turnedOnLocation = false;
if (!turnedOnLocation) {
startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
}
boolean appSetup = prefManager.get("app_setup", false);
if (!appSetup) {
viewModel.observeLoadStatus().observe(this, status -> {
progressBar.setProgress(status + "");
});
}
}
}
一切运行顺利,但是,当我离开此 Activity 并返回时,应用程序崩溃并出现错误:
Process: com.testapp.testapp, PID: 29865
java.lang.RuntimeException: Unable to resume activity {com.testapp.testapp/com.testapp.testapp.ui.splash.SplashActivity}: java.lang.IllegalArgumentException: This source was already added with the different observer
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3609)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3649)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1663)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6524)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:888)
Caused by: java.lang.IllegalArgumentException: This source was already added with the different observer
at androidx.lifecycle.MediatorLiveData.addSource(MediatorLiveData.java:89)
at com.testapp.testapp.ui.splash.SplashViewModel.fetchSensorLocations(SplashViewModel.java:25)
at com.testapp.testapp.ui.splash.SplashViewModel.observeLoadStatus(SplashViewModel.java:17)
at com.testapp.testapp.ui.splash.SplashActivity.observeViewModels(SplashActivity.java:121)
at com.testapp.testapp.ui.splash.SplashActivity.onResume(SplashActivity.java:77)
at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1355)
at android.app.Activity.performResume(Activity.java:7138)
我将非常感谢您的解释以及为什么我一直收到此错误。
谢谢
最佳答案
您正在 MediatorLiveData
的同一源上设置 2 观察者。
您只能为每个源设置 1 个观察者,否则会抛出 IllegalStateException
,就像您的情况一样。
将 observe
方法从 onResume()
移至 onCreate()
。
当您将 Activity 置于后台时,ViewModel 不会被销毁。它仍然在内存中,等待 Activity 返回前台。它只有在 Activity 完全关闭时才会被销毁。
如果您想停止观察特定来源,只需使用removeSource()
。
如果您想再次开始观察源,请使用addSource()
。
关于java.lang.IllegalArgumentException : This source was already added with the different observer 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54063693/