Coming soon - Get a detailed view of why an account is flagged as spam!
view details

This post has been de-listed

It is no longer included in search results and normal feeds (front page, hot posts, subreddit posts, etc). It remains visible only via the author's post history.

1
Anyone used SavedStateHandle with a shared ViewModel?
Post Body

I've tried using SavedStateHandle with little success. It works when I'm using the app, as in I can set and get values from the handle instance across Fragments but the values won't survive process death. In any situation: Force Close, End Task with task switcher...The values in the handle are always null on app launch (and no keys exist either).

Some code below.

VM Factory that I'm using:

@Singleton
class HomeViewModelFactory @Inject constructor(
    private val getStationsUseCase: GetStationsUseCase,
    private val getAllStationCodesUseCase: GetAllStationCodesUseCase,
    private val getDeparturesUseCase: GetDeparturesUseCase,
    private val getJourneyPlanUseCase: GetJourneyPlanUseCase,
    private val getServiceDetailsUseCase: GetServiceDetailsUseCase,
    private val getArrivalsUseCase: GetArrivalsUseCase
) : ViewModelFactory<HomeViewModel> {

    override fun create(handle: SavedStateHandle): HomeViewModel {
        return HomeViewModel(handle, getStationsUseCase, getAllStationCodesUseCase,
                getDeparturesUseCase, getJourneyPlanUseCase, getServiceDetailsUseCase, getArrivalsUseCase)
    }
}

Some utility classes/functions:

class GenericSavedStateViewModelFactory<out V : ViewModel>(
    private val viewModelFactory: ViewModelFactory<V>,
    owner: SavedStateRegistryOwner,
    defaultArgs: Bundle? = null
) : AbstractSavedStateViewModelFactory(owner, defaultArgs) {
    @Suppress("UNCHECKED_CAST")
    override fun <T : ViewModel> create(
        key: String,
        modelClass: Class<T>,
        handle: SavedStateHandle
    ): T {
        return viewModelFactory.create(handle) as T
    }
}

@MainThread
inline fun <reified VM: ViewModel> SavedStateRegistryOwner.withFactory(
    factory: ViewModelFactory<VM>,
    defaultArgs: Bundle? = null
) = GenericSavedStateViewModelFactory(factory, this, defaultArgs)

// Implemented by VM factories
interface ViewModelFactory<out V : ViewModel> {
    fun create(handle: SavedStateHandle): V
}

How I access my ViewModel in Fragments:

@Inject
lateinit var viewModelFactory: HomeViewModelFactory

private val viewModel: HomeViewModel by activityViewModels { withFactory(viewModelFactory) }

In my ViewModel I have this (for testing):

fun depStationText(): String? = handle.get<String>("depStation")

fun saveDepStation(crs: CRS) {
    depStation.postValue(crs)
    handle.set("depStation", crs.crs)
}

And in my Fragment (after the "depStation" has been set):

 Log.i(HomeFragment::class.java.simpleName, "DepStation: ${viewModel.depStationText()}")

This log statement above returns a good values while the app is open, but after process death or an ended task it's always null. Is there something I'm missing here?

Author
Account Strength
90%
Account Age
7 years
Verified Email
Yes
Verified Flair
No
Total Karma
3,195
Link Karma
2,282
Comment Karma
761
Profile updated: 5 days ago
Posts updated: 1 day ago
Android Engineer

Subreddit

Post Details

We try to extract some basic information from the post title. This is not always successful or accurate, please use your best judgement and compare these values to the post title and body for confirmation.
Posted
4 years ago