My app uses hilt and I have some work with LoadManager
inside my activity that read contacts using ContentResolver
and when I finish work I get the cursor that I send to my viewModel in order to process the data and do some business logic which for that I declared the following on top of my activity :
@AndroidEntryPoint
class MainActivity : ComponentActivity(), LoaderManager.LoaderCallbacks<Cursor> {
private val contactsViewModel: ContactsViewModel by viewModels()
...
such that I use it inside onLoadFinished
:
override fun onLoadFinished(loader: Loader<Cursor>, cursor: Cursor?) {
contactsViewModel.updateContactsListFromCursor(cursor, loader.id)
}
Inside my viewModel I have the following code which updates the ui state of the list with the contacts to be displayed:
data class ContactsListUiState(
val contacts: MutableList<Contact>,
val searchFilter: String)
@HiltViewModel
class ContactsViewModel @Inject constructor() : ViewModel() {
private val _contactsListUiState =
MutableStateFlow(ContactsListUiState(mutableStateListOf(), ""))
val contactsListUiState: StateFlow<ContactsListUiState> = _contactsListUiState.asStateFlow()
private fun updateContactsList(filter: String) {
viewModelScope.launch(Dispatchers.IO) {
...
_contactsListUiState.update { currentState ->
currentState.copy(contacts = list, searchFilter = filter)
}
}
Finally, I am supposed to display the contacts that a LazyColumn
and I pass the viewModel to my composable function using hilt following the official documentation :
@Composable
fun ContactsListScreen(
navController: NavController,
modifier: Modifier = Modifier, viewModel: ContactsViewModel = hiltViewModel()
) {
val uiState by viewModel.contactsListUiState.collectAsStateWithLifecycle()
...
But when i access uiState.contacts
it is empty and my lists does not show anything and I also noticed that the contactsViewModel
which I used in the activity is not the same viewModel instance that I got from hiltViewModel()
inside the composable function which probably causes this problem..
Any suggestions how to share the sameViewModel between the activity and the composable functions assuming that I have to call the viewModel from the onLoadFinished function(which is not composable) where I get the cursor therefore I must have a viewModel reference inside the activity itself
ViewModel's
init{…}
block and verifying its not being called more than once? – Mongby viewModels()
inside the activity provides a different instance than thehiltViewModel()
inside the composable functions – SeafaringhiltViewModel()
supposed to be scoped to the "closest"LifeCycleOwner
? in this is is my activity – SeafaringonLoadFinished
callback which is not composable so I cannot usehiltViewModel()
there.. – SeafaringviewModel()
factory instead ofhiltViewModel()
? just to check if it would make any difference, -androidx.lifecycle.viewmodel.compose.viewModel
– MongviewModel()
andhiltViewModel()
seems to work only when I pass in the activity as theViewModelStoreOwner
likehiltViewModel(this)
– Seafaring