使用观察到在Kotlin中更新另一个观察的变量
我首先尝试使用observe 处理来自API 的响应。稍后在观察处理的变量后,我想将其保存到数据库中。
变量 tokenFromApi
在 tokenResponseFromApi
的观察者内部更新。是否可以在 tokenResponseFromApi
的观察者之外观察到 tokenFromApi
?调试时,应用程序启动时代码未进入 tokenFromApi
观察者内部。
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
var tokenResponseFromApi: LiveData<String>? = MutableLiveData<String>()
var tokenFromApi: LiveData<TokenEntity>? = MutableLiveData<TokenEntity>()
tokenResponseFromApi?.observe(viewLifecycleOwner, Observer {
tokenResponseFromApi ->
if (tokenResponseFromApi != null) {
tokenFromApi = viewModel.convertTokenResponseToEntity(tokenResponseFromApi, dh.asDate)
}
})
tokenFromApi?.observe(viewLifecycleOwner, Observer {
tokenFromApi ->
if (tokenFromApi != null) {
viewModel.saveTokenToDB(repo, tokenFromApi)
}
})
}
I am trying first handle the response from API by using observe. Later after observing the handled variable I want to save it to database.
The variable tokenFromApi
is updated inside tokenResponseFromApi
's observer. Is it possible to observe tokenFromApi
outside the observer of tokenResponseFromApi
? When debugged, the code did not enter inside tokenFromApi
observer when the app started.
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
var tokenResponseFromApi: LiveData<String>? = MutableLiveData<String>()
var tokenFromApi: LiveData<TokenEntity>? = MutableLiveData<TokenEntity>()
tokenResponseFromApi?.observe(viewLifecycleOwner, Observer {
tokenResponseFromApi ->
if (tokenResponseFromApi != null) {
tokenFromApi = viewModel.convertTokenResponseToEntity(tokenResponseFromApi, dh.asDate)
}
})
tokenFromApi?.observe(viewLifecycleOwner, Observer {
tokenFromApi ->
if (tokenFromApi != null) {
viewModel.saveTokenToDB(repo, tokenFromApi)
}
})
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您的问题是您在设置过程中在
tokenfromapi
上注册观察者,当您获得API响应时,您将替换tokenfromapi
没有在上面注册一个观察者。因此,如果它发出价值,您将永远不会知道。 The only observer you have registered is the one on the discardedtokenFromApi
which is never used by anythingHonestly your setup here isn't how you're supposed to use
LiveData
.与其为每个响应创建一个全新的tokenfromapi
,您只需要一个livedata
即可观察。当有一个新值(例如API令牌)时,您 setlivedata
,所有观察者都会看到并对其做出反应。一旦连接,它就完成了,一切都起作用。您现在的方式是,您有一个需要拆开的数据源,替换为新的数据源,然后与之重新连接 - 每次有新数据,如果您明白了我的意思。
理想情况下,片段是UI,因此对事件有反应(通过观察
livedata
之类的数据源,并将UI事件推到视图模型(有人单击此内容等)。存储确实属于VM - 您已经在这里调用的VM中使用了一半,对livedata
s属于VM,有关VM内部发生的事情以及应用程序的其余部分 - 它们揭示了UI需要反应的信息。 part of your problemHave a look at the App Architecture guide (that's the UI Layer page but it's worth being familiar with the rest), but this is a basic sketch of how I'd do it:
so it's basically all contained within the VM - the UI stuff like fragments doesn't need to know anything about API calls ,无论是存储的东西,如何存储。 VM可以在需要发出一些新数据,更新某些状态或其他任何内容时更新其暴露的
livedata
对象,这对VM之外的事物而不是内部工作很有趣。片段仅观察
对其感兴趣的哪一个,并根据需要更新UI。(我知道回调情况可能比此类情况更复杂,例如保存到数据库可能涉及
flow
或其他东西。但是,这个想法是相同的 - 在其回调/结果函数中,将值推到您的livedata
适当地,因此观察者可以接收它,并且使用livedata
或flow
flow flow 新的tokenentity
被推到一个呼叫savetokentodb
的观察者,如果这种管道设置是有道理的!关于那些中间步骤Your problem is that you're registering the observer on
tokenFromApi
during setup, and when you get your API response, you're replacingtokenFromApi
without registering an observer on it. So if it ever emits a value, you'll never know about it. The only observer you have registered is the one on the discardedtokenFromApi
which is never used by anythingHonestly your setup here isn't how you're supposed to use
LiveData
. Instead of creating a whole newtokenFromApi
for each response, you'd just have a singleLiveData
that things can observe. When there's a new value (like an API token) you set that on theLiveData
, and all the observers see it and react to it. Once that's wired up, it's done and it all works.The way you're doing it right now, you have a data source that needs to be taken apart, replaced with a new one, and then everything reconnected to it - every time there's a new piece of data, if you see what I mean.
Ideally the Fragment is the UI, so it reacts to events (by observing a data source like a
LiveData
and pushes UI events to the view model (someone clicked this thing, etc). That API fetching and DB storing really belongs in the VM - and you're already half doing that with those functions in the VM you're calling here, right? TheLiveData
s belong in the VM because they're a source of data about what's going on inside the VM, and the rest of the app - they expose info the UI needs to react to. Having theLiveData
instances in your fragment and trying to wire them up when something happens is part of your problemHave a look at the App Architecture guide (that's the UI Layer page but it's worth being familiar with the rest), but this is a basic sketch of how I'd do it:
so it's basically all contained within the VM - the UI stuff like fragments doesn't need to know anything about API calls, whether something is being stored, how it's being stored. The VM can update one of its exposed
LiveData
objects when it needs to emit some new data, update some state, or whatever - stuff that's interesting to things outside the VM, not its internal workings. The Fragment justobserve
s whichever one it's interested in, and updates the UI as required.(I know the callback situation might be more complex than that, like saving to the DB might involve a
Flow
or something. But the idea is the same - in its callback/result function, push a value to yourLiveData
as appropriate so observers can receive it. And there's nothing wrong with usingLiveData
orFlow
objects inside the VM, and wiring those up so a newTokenEntity
gets pushed to an observer that callssaveTokenToDb
, if that kind of pipeline setup makes sense! But keep that stuff private if the outside world doesn't need to know about those intermediate steps