Can anyone please explain this expression properly for me... It seems to be the problem I'm facing currently.
Starts to listen the given source LiveData, onChanged observer will be called when source value was changed.
onChangedcallback will be called only when this MediatorLiveData is active.If the given LiveData is already added as a source but with a different Observer,
IllegalArgumentExceptionwill be thrown.
I currently have the following as my 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);
});
}
}
In the activity, I have this:
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 + "");
});
}
}
}
Everything runs as smoothly, however, when I leave this activity and return, the application crashes with the error:
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)
I will really appreciate an explanation and why I keep getting this error.
Thanks