How do I use the new Saved State Module of ViewModel

For using Saved State module for View Model you have to add the androidx.lifecycle:lifecycle-viewmodel-savedstate dependency to your project. This example has been written based on version 1.0.0-rc03.

Please add the following line to your project Gradle file:
implementation 'androidx.lifecycle:lifecycle-viewmodel-savedstate:1.0.0-rc03'

ViewModel implementation:

class SavedStateViewModel(private val state: SavedStateHandle) : ViewModel() {

    val liveData = state.getLiveData("liveData", Random.nextInt().toString())

    fun saveState() {
        state.set("liveData", liveData.value)
    }
}

Activity implementation:

class SavedStateActivity : AppCompatActivity() {

    lateinit var viewModel: SavedStateViewModel;

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val binding: ActivityStateBinding = DataBindingUtil.setContentView(this, R.layout.activity_state)

        viewModel = ViewModelProvider(this, SavedStateViewModelFactory(this.application, this)).get(SavedStateViewModel::class.java)

        binding.viewModel = viewModel
        binding.lifecycleOwner = this
    }

    override fun onSaveInstanceState(outState: Bundle) {
        if(::viewModel.isInitialized)
            viewModel.saveState()

        super.onSaveInstanceState(outState)
    }
}

I have tested this code and it works fine.


I am adding an answer to this old post just in case someone might find it useful.

I managed to do it as follows:

  • Add the following dependency to your "build.gradle (Module: app)" file
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
  • Add savedState: SavedStateHandle property to the constructor of the ViewModel
class SelectedTracksViewModel(private val savedState: SavedStateHandle) : ViewModel() {

    companion object {
        private const val SAVED_TRACK_INDEX = "savedTrackIndex"
    }

    private var trackIndex: Int
      set(value) {
        field = value
        // Simply update the savedState every time your saved property changes
        savedState.set(SAVED_TRACK_INDEX, value)
      }

    init {
        trackIndex = savedState.get<Int>(SAVED_TRACK_INDEX) ?: 0
    }

    fun moveToNextTrack() {
        trackIndex++ 
        // Initially I was updating savedState here - now moved to setter
        
        // Some more code here
    }    
}

Finally in the activity/fragment

    private val selectedTracksViewModel: SelectedTracksViewModel by lazy {
        ViewModelProvider(this).get(SelectedTracksViewModel::class.java)
    }

And that's it. No need for SavedStateViewModelFactory, simply add the savedState property to your ViewModel constructor and update it when tracked properties change. Everything else works as if you're not using savedState: SavedStateHandle and this way is very similar to the traditional onSaveInstanceState(Bundle) in activities/fragments.

Update: Initially I was updating savedState after changing trackIndex. This means one has to update savedState every time saved properties are changed. This is a huge potential future bug if one forgets to add that line. A better and more robust pattern is to update the savedState in the setter of the property.