Search code examples
androidkotlinviewmodelandroid-livedatasavestate

java.lang.IllegalStateException: Failed to find type for when decoding androidx.lifecycle.SavedStateHandle@8019b8e


Hello I am receiving the error in the title based off the following code:

class MainViewModel (application: Application, private val savedStateHandle: SavedStateHandle) : AndroidViewModel(application){

var showPod : MutableLiveData<Boolean>
        set(value) {
            savedStateHandle.set("showPod", value)
        }
        get() {
            return savedStateHandle.getLiveData<Boolean>("showPod")
        }
}

I've explicitly defined the type to be Boolean in the MutableLiveData, I'm not sure why the error persists..


Solution

  • When you do:

    set(value) {
        savedStateHandle.set("showPod", value)
    }
    

    The value is the type of your variable - a MutableLiveData<Boolean>, which you can't put in a SavedStateHandle. That means that the 'easiest' way to solve the problem is to change your code to:

    set(value) {
        savedStateHandle.set("showPod", value.value)
    }
    

    But having a var that is a MutableLiveData doesn't make much sense at all - you don't expose a var of something that is Mutable. Instead, you would want to do one of two things:

    1. Use the MutableLiveData directly

    val showPod = savedStateHandle.getLiveData<Boolean>("showPod")
    

    Where then you would use it by either using viewModel.showPod.observe(...) or viewModel.showPod.value = ... - writing the value to the MutableLiveData automatically writes it to the SavedStateHandle (that's the whole reason it is a MutableLiveData in the first place).

    2. Expose a LiveData and a separate setter

    // Keep the mutable version private
    private val showPodLiveData = savedStateHandle.getLiveData<Boolean>("showPod")
    
    // Expose a not Mutable LiveData and a separate setter
    val showPod : LiveData<Boolean> = showPodLiveData
    
    fun setShowPod(boolean value) {
        showPodLiveData.value = value
    }
    

    Here, we ensure that we only expose a LiveData (where the .value is not writable) and completely control the setter behavior as a separate method.