cr0*_*9xx 8 java android mvvm android-livedata android-architecture-components
任何人都可以为我正确解释这个表达......这似乎是我目前面临的问题。
开始侦听给定的源 LiveData,当源值更改时将调用 onChanged 观察者。
onChanged
只有当此 MediatorLiveData 处于活动状态时才会调用回调。如果给定的 LiveData 已作为源添加但具有不同的观察者,
IllegalArgumentException
则将抛出。
我目前有以下作为我的 ViewModel (Called 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);
});
}
}
Run Code Online (Sandbox Code Playgroud)
在活动中,我有这个:
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 + "");
});
}
}
}
Run Code Online (Sandbox Code Playgroud)
一切都运行得很顺利,但是,当我离开此活动并返回时,应用程序因错误而崩溃:
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)
Run Code Online (Sandbox Code Playgroud)
我将非常感谢解释以及为什么我不断收到此错误。
谢谢
您正在同一源上设置2 个MediatorLiveData
观察者。
您只能为每个 source 设置 1 个观察者,否则IllegalStateException
会抛出一个异常,就像您的情况一样。
将您的observe
方法从onResume()
移至onCreate()
。
当您将 Activity 置于后台时,ViewModel 不会被破坏。它仍在内存中,等待 Activity 返回前台。只有当活动完全关闭时它才会被销毁。
如果您想停止观察特定来源,只需使用removeSource()
.
如果您想再次开始观察源,请使用addSource()
。
归档时间: |
|
查看次数: |
5014 次 |
最近记录: |