LIVEDATA的Lateinit var
在我的ViewModel中,我有一个LateInit var
可以容纳一些Livedata。初始化此变量的方式取决于数据和当前日期。无法在SQL中做到这一点。这是ViewModel:
class MainViewModel {
lateinit var timeStamps: LiveData<List<TimeStamp>>
init {
viewModelScope.launch {
val db = RoomDB.getInstance(application).timeStampDao()
val lastTimeStamp = db.getLast()
if (lastTimeStamp == null
|| (lastTimeStamp.instant < setToStartOfDay(Calendar.getInstance()).timeInMillis)
&& lastTimeStamp.action == ACTION.END_WORK) {
timeStamps = db.getAllAfterLive(Calendar.getInstance().timeInMillis)
} else {
db.getLastAction(ACTION.START_WORK)?.let { lastStartWork ->
val startOfDay = setToStartOfDay(initCalendar(lastStartWork.instant)).timeInMillis
db.getFirstActionAfter(ACTION.START_WORK, startOfDay)?.let {
timeStamps = db.getAllAfterLive(it.instant)
}
}
}
在我的活动中,我在这里访问timestamps
:
override fun onCreate(savedInstanceState: Bundle?) {
viewModel.timeStamps.observe(this) { list -> recordsAdapter.submitList(list) }
这导致notialialized propertyAccessexecception
:onCreate运行速度要比timestamps
平行启动更快。
我通过引入另一个lateInit var
来解决此问题:
class MainViewModel {
lateinit var timeStamps: LiveData<List<TimeStamp>>
lateinit var timeStampsInitializedCallback: () -> Unit
init {
viewModelScope.launch {
// inspect the data and initialize timeStamps
timeStampsInitializedCallback()
}
我以increate
的初始化:
override fun onCreate(savedInstanceState: Bundle?) {
viewModel.timeStampsInitializedCallback = {
viewModel.timeStamps.observe(this) { list -> recordsAdapter.submitList(list) }
}
这有效,但它引入了竞赛条件。如果时间戳的初始化
在初始化回调之前出乎意料地完成,我会得到另一个notialialized propertyaccessexception
,然后回到我开始的地方。
如何改进此代码?
In my ViewModel I have a lateinit var
to hold some LiveData. The way this variable is initialized depends on the data and the current date. Can't do it in SQL. This is the ViewModel:
class MainViewModel {
lateinit var timeStamps: LiveData<List<TimeStamp>>
init {
viewModelScope.launch {
val db = RoomDB.getInstance(application).timeStampDao()
val lastTimeStamp = db.getLast()
if (lastTimeStamp == null
|| (lastTimeStamp.instant < setToStartOfDay(Calendar.getInstance()).timeInMillis)
&& lastTimeStamp.action == ACTION.END_WORK) {
timeStamps = db.getAllAfterLive(Calendar.getInstance().timeInMillis)
} else {
db.getLastAction(ACTION.START_WORK)?.let { lastStartWork ->
val startOfDay = setToStartOfDay(initCalendar(lastStartWork.instant)).timeInMillis
db.getFirstActionAfter(ACTION.START_WORK, startOfDay)?.let {
timeStamps = db.getAllAfterLive(it.instant)
}
}
}
Here I access timeStamps
in my Activity:
override fun onCreate(savedInstanceState: Bundle?) {
viewModel.timeStamps.observe(this) { list -> recordsAdapter.submitList(list) }
This leads to a UninitializedPropertyAccessException
: onCreate runs faster than the timeStamps
initialization launched in parallel.
I fixed this by introducing another lateinit var
for a callback:
class MainViewModel {
lateinit var timeStamps: LiveData<List<TimeStamp>>
lateinit var timeStampsInitializedCallback: () -> Unit
init {
viewModelScope.launch {
// inspect the data and initialize timeStamps
timeStampsInitializedCallback()
}
which I initialize in onCreate
:
override fun onCreate(savedInstanceState: Bundle?) {
viewModel.timeStampsInitializedCallback = {
viewModel.timeStamps.observe(this) { list -> recordsAdapter.submitList(list) }
}
This works, but it introduces a race condition. Should the initialization for timeStamps
unexpectedly finish before the callback is initialized, I'd get another UninitializedPropertyAccessException
and be back where I started.
How can I improve this code?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您还可以使用
livedata
builder函数:
livedata
代码块在livedata
变得活跃时开始执行,并在可配置超时后自动取消,当livedata
变得不活跃时。You can also use
liveData
builder function:The
liveData
code block starts executing whenLiveData
becomes active and is automatically canceled after a configurable timeout when theLiveData
becomes inactive.最简单的选项似乎
mutableLivedata
:取决于Coroutine的所作所为,可能还有其他选项(例如,
flow> flow> flow
上的aslived> aslivedata()
,中级属性
)。The simplest option seems like
MutableLiveData
:Depending on what the coroutine is doing, there may be other options (e.g.,
asLiveData()
on aFlow
,MediatorLiveData
).