I have an app with two activities. Activity1
changes a State
stored in a ViewModel
, then starts Activity2
. But somehow, the state change is only reflected in Activity1
, not in Activity2
.
ViewModel
class MyViewModel : ViewModel() {
var hasChanged: Boolean by mutableStateOf(false)
}
Composable of Activity1
@Composable
fun Screen1() {
val context = LocalContext.current
val viewModel: MyViewModel = viewModel()
Column {
Text("State changed: " + viewModel.hasChanged.toString())
Button(
onClick = {
viewModel.hasChanged = true
startActivity(context, Intent(context, Activity2::class.java), null)
}
) {
Text("Change State!")
}
}
}
Composable of Activity2
@Composable
fun Screen2() {
val viewModel: MyViewModel = viewModel()
Text("State changed: " + viewModel.hasChanged.toString()) # stays 'false'
}
Behavior of the app
Activity1
correctly shows the state to be false
, initially Activity1
correctly displays the state to be true
Activity2
opens but still shows the state to be false
Question
Why is the state change not reflected in Activity2
and can this be fixed?
ViewModels are unique to classes that implement ViewModelStoreOwner
@Composable
public inline fun <reified VM : ViewModel> viewModel(
viewModelStoreOwner: ViewModelStoreOwner = checkNotNull(LocalViewModelStoreOwner.current) {
"No ViewModelStoreOwner was provided via LocalViewModelStoreOwner"
},
key: String? = null,
factory: ViewModelProvider.Factory? = null,
extras: CreationExtras = if (viewModelStoreOwner is HasDefaultViewModelProviderFactory) {
viewModelStoreOwner.defaultViewModelCreationExtras
} else {
CreationExtras.Empty
}
ComponentActivity
implements ViewModelStoreOwner
, so it's a ViewModelStoreOwner
that contains its own ViewModel
instances and uses a HashMap
to get same ViewModel
for key provided as String.
val vm: MyViewModel = ViewModelProvider(owner = this)[MyViewModel::class.java]
This is how they are created under the hood. This here is Activity or Fragment depending on where ViewModelProvider's owner param is set at. In Compose ViewModelStore owner is accessed by LocalViewModelStoreOwner.current
You need to pass your hasChanged
between Activities
using Bundle
, or have a Singleton repository or UseCase class that you can inject to both ViewModels or use local db or another methods to pass data between Activities.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.