BenjyTec
BenjyTec

Reputation: 10887

ArrayList is not stored in SavedStateHandle

In my ViewModel, I have set up a propery like this:

class MyViewModel(private val savedStateHandle: SavedStateHandle) : ViewModel() {
    private var _wrongNumbers: ArrayList<Int> = savedStateHandle.get<ArrayList<Int>>("MY_KEY") ?: arrayListOf()
        set(value) {
            field = value
            savedStateHandle["MY_KEY"] = value
        }
}

I then add elements to that ArrayList inside of the ViewModel:

fun addNumber(newNumber: Int) {
    _wrongNumbers.add(newNumber)
}

However, after the process is killed and the SavedStateHandle is restored, the _wrongNumbers ArrayList is empty. Why is this happening?

Upvotes: 1

Views: 29

Answers (2)

tyg
tyg

Reputation: 15753

Although the other answer already explains the reason why it doesn't work, the proper solution would be to prevent this in the first case:

class MyViewModel(private val savedStateHandle: SavedStateHandle) : ViewModel() {
    private var _wrongNumbers: List<Int> = savedStateHandle.get<ArrayList<Int>>("MY_KEY") ?: arrayListOf()
        set(value) {
            field = value
            savedStateHandle["MY_KEY"] = value
        }

    fun addNumber(newNumber: Int) {
        _wrongNumbers += newNumber
    }
}

_wrongNumbers is now of type List which doesn't allow modifications. It forces you to use _wrongNumbers += newNumber instead of _wrongNumbers.add(newNumber), which creates a new list with newNumber added at the end and then uses the custom setter to save the new list in _wrongNumbers, which in turn properly writes the SavedStateHandle.

Upvotes: 0

BenjyTec
BenjyTec

Reputation: 10887

The issue with your implementation is that the _wrongNumbers is never actually registered to the SavedStateHandle, as you don't assign any value to it that triggers your custom setter. Calling add() does not invoke the setter.
When the process is killed and the ViewModel later is restored, there is no entry with MY_KEY in the SavedStateHandle and thus it is again initialized to arrayListOf().

The problem is fixed once you initialize your _wrongNumbers once.

Upvotes: 0

Related Questions