[Android] ViewModel-SavedState-ktx 2.2.0 Released

Takumi WADA
ViewModel-SavedState-ktx
3 min readFeb 12, 2020
ViewModel-SavedState-ktx 2.2.0

# What is ViewModel-SavedState-ktx

ViewModel-SavedState-ktx is a library that allows you to easily use SavedStateHandle of ViewModel-SavedState by Delegated Property.

# What is ViewModel-SavedState

Up to now, UI states is usually stored in onSavedInstanceState and restored in onCreate. From now on, you can store and restore UI states by SavedStateHandle using ViewModel-SavedState.

# Why use ViewModel-SavedState

ViewModel has been kept alive when configuration changes occurred, but ViewModel has been destroyed when Activity killed by OS. By using ViewModel-SavedState, ViewModel save its property when Activity killed by OS.

# How to use ViewModel-SavedState

## How to get SavedStateHandle

  • You can get a SavedStateHandle instance via ViewModel’s constructor.

## How to pass SavedStateHandle to ViewModel constructor

  • If you call by viewModels() in Activity or Fragment, SavedStateHandle is automatically passed. The intent.extra or arguments is passed automatically to SavedStateHandle.
  • If you want to pass parameters other than SavedStateHandle or Application, SavedStateHandle into ViewModel's constructor, you pass a ViewModel's factory into by viewModels. The ViewModel’s factory needs to extend AbstractSavedStateViewModelFactory. The intent.extra or arguments needs to pass manually to the ViewModel's factory if need it.

## How to use SavedStateHandle

  • You can use a value by SavedStateHandle#get(key) and SavedStateHandle#set(key, value). The value is initialized by value of same key in intent.extra or arguments.
  • You can use a LiveData instance by SavedStateHandle#getLiveData(key). If you change the LiveData instance’s value, a value of SavedStateHandle is changed.

# Problems in ViewModel-SavedState

  • If you get a value by SavedStateHandle#get(key), you don't only change the value but also need to call SavedStateHandle#set(key, value).
  • SavedStateHandle requires a key to use. The key needs to be same as a key of intent.extra or arguments.
  • SavedStateHandle has restrictions on available types.

# Solutions by ViewModel-SavedState-ktx

  • When you change the value, SavedStateHandle#set(key, value) is automatically called by Delegated Properties.
  • ViewModel-SavedState-ktx don’t requires a key to use SavedStateHandle. Instead, it uses property name. It provides extension methods for specifying property name in Intent and Bundle.
  • You can use any type using SavedStateAdapter that converts between the type used in SavedStateHandle and the type actually used in ViewModel.

# How to use ViewModel-SavedState-ktx

Pass parameters to the Intent or Bundle with an extension function using a property reference.

class SampleActivity : AppCompatActivity(R.layout.sample_activity) {
private val viewModel: SampleViewModel by viewModels()
companion object {
@JvmStatic
fun createIntent(context: Context): Intent {
return Intent(context, SampleActivity::class.java).also {
it.putExtra(SampleViewModel::text, "sample")
}
}
}
}

You can use the extension function of SavedStateHandle in Delegated Property to get values ​​and LiveData. Arbitrary type conversion can be performed with initial value setting and SavedStateAdapter.

class SampleViewModel(
savedStateHandle: SavedStateHandle
) : ViewModel() {
val text: String by savedStateHandle.property()
val count: MutableLiveData<Int> by savedStateHandle.liveData(initialValue = 0)
val timeUnit: MutableLiveData<TimeUnit?> by savedStateHandle.liveData(object : SavedStateAdapter<TimeUnit?, Int?> {
override fun toSavedState(value: TimeUnit?): Int = value?.ordinal
override fun fromSavedState(state: Int?): TimeUnit? = state?.let { TimeUnit.values()[it] }
})
}

# ViewModel-SavedState-ktx 2.2.0 is here

--

--