[英]How to make sure I use the same instance of the ViewModel?
In the MainActivity I create a ViewModel object using:在 MainActivity 中,我使用以下方法创建了一个 ViewModel 对象:
class MainActivity : ComponentActivity() {
private val viewModel by viewModels<MainViewModel>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
if(viewModel.isActive()) {
//Do stuff...
} else {
//Do other stuff...
}
}
}
}
And inside a composable function, I'm injecting it using Hilt:在可组合函数中,我使用 Hilt 将其注入:
@Composable
fun ActivateScreen(
viewModel: MainViewModel = hiltViewModel()
) {
Scaffold(
topBar = { /... },
content = {
UiContent(
onClick = {
viewModel.activate()
}
)
}
)
}
But it seems to me that the view model objects are different objects, because when I click activate, the change is not propagated to the MainActivity.但在我看来,视图模型对象是不同的对象,因为当我单击激活时,更改不会传播到 MainActivity。 I need to restart the app in order to see the change.
我需要重新启动应用程序才能看到更改。 How to make sure I'm using the same instance?
如何确保我使用的是同一个实例? Any help would be greatly appreciated.
任何帮助将不胜感激。
A quick way to see that is not the same is to place a breakpoint in the init block of the viewmodel, if the call inside mainactivity executes it and the call inside your composable does it, that will tell you that the two instances are different.一种快速查看不相同的方法是在 viewmodel 的 init 块中放置一个断点,如果 mainactivity 内部的调用执行它并且可组合项内部的调用执行它,这将告诉您这两个实例是不同的。 If you are already creating the viewmodel in your activity with hilt, just pass it as a parameter to your composable
如果您已经在活动中使用 hilt 创建视图模型,只需将其作为参数传递给您的可组合项
class MainActivity : ComponentActivity() {
private val viewModel by viewModels<MainViewModel>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
if(viewModel.isActive()) {
//Do stuff...
ActivateScreen(viewmodel)
} else {
//Do other stuff...
}
}
}
}
@Composable
fun ActivateScreen(
viewModel: MainViewModel
) {
Scaffold(
topBar = { /... },
content = {
UiContent(
onClick = {
viewModel.activate()
}
)
}
)
}
If you want to use Dagger Hilt you should do like this: (I also used a similar code in my project)如果你想使用 Dagger Hilt 你应该这样做:(我在我的项目中也使用了类似的代码)
@AndroidEntryPoint
class MainActivity : ComponentActivity() {
@Inject
lateinit var viewModel: MainViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
if(viewModel.isActive()) {
//Do stuff...
ActivateScreen(viewmodel)
} else {
//Do other stuff...
}
}
}
} }
@Composable
fun ActivateScreen(
viewModel: MainViewModel
) {
Scaffold(
topBar = { /... },
content = {
UiContent(
onClick = {
viewModel.activate()
}
)
}
)
} }
@HiltAndroidApp
class MyApp: Application()
And in Manifest.xml在 Manifest.xml 中
<application
android:name=".MyApp"
The reason why you are not seeing the change propagated to Main activity is perhaps not due to an issue of the instances of the viewModel being 2 different instances, but more than likely it is because Compose isn't triggering a recomposition because the value checked in MainActivity
if(viewModel.isActive())
is not a state that Compose is aware of.您没有看到更改传播到 Main 活动的原因可能不是由于 viewModel 的实例是 2 个不同实例的问题,但很可能是因为 Compose 没有触发重组,因为值已签入
MainActivity
if(viewModel.isActive())
不是 Compose 知道的状态。 In order for the recomposition to trigger, you will need to read a state that compose is aware of.为了触发重组,您需要读取 compose 知道的状态。 One way to achieve this is to use
mutableStateOf
in the viewModel, then rather than having isActive
be a function, it can be a val
with a custom getter, or you can use the delegate form.实现此目的的一种方法是在 viewModel 中使用
mutableStateOf
,而不是让isActive
成为一个函数,它可以是一个带有自定义 getter 的val
,或者您可以使用委托形式。
var isActive by mutableStateOf(false)
As for checking if the two are indeed the same instance, if you place a breakpoint in the code after each one is assigned, you can get the hashcode, which unless you've overridden hashCode
it will default to be the memory address of the object, if both instances have the same memory address, they are the almost certainly the same instance.至于检查两者是否确实是同一个实例,如果你在每一个赋值后在代码中打断点,你就可以得到hashcode,除非你覆盖了
hashCode
,否则它默认是对象的内存地址,如果两个实例具有相同的内存地址,那么它们几乎可以肯定是同一个实例。 Another way would be to pass them around until you can use ===
to do a reference comparison rather than a equality comparison, which will tell if they are the same instance or not.另一种方法是传递它们,直到您可以使用
===
进行引用比较而不是相等比较,这将判断它们是否是相同的实例。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.