随着Android体系结构组件的稳定,我开始将所有基本ViewModel的更新到新的实现ViewModel.根据我的理解,LiveData建议使用它来保存Model类,因为它更好地处理生命周期.
我喜欢使用Data Binding它,因为它使代码在Java/Kotlin方面更清晰,并且不需要"观察"值更改来更新UI.但是,Data Binding如果Model(或ViewModel)扩展BaseObservable,LiveData则仅使用监视数据的布局会发生变化.我理解的主要目标之一LiveData是以编程方式观察和更新UI,但对于简单的更新,Data Binding非常有用.
这个问题已经报道过(GitHub和Stack Overflow),并且首先说版本1.0会有它,现在据说这个功能正在开发中.
为了同时使用LiveData和Data Binding,我创建了一个非常简单的类实现,它扩展了BaseObservable:
import android.arch.lifecycle.LiveData
import android.arch.lifecycle.MutableLiveData
import android.databinding.BaseObservable
class ObservableMutableLiveData<T>() : BaseObservable() {
private var data: MutableLiveData<T> = MutableLiveData()
constructor(data: T) : this() {
this.data.value = data
}
public fun set(value: T) {
if (value != data.value) {
data.value = value …Run Code Online (Sandbox Code Playgroud) android kotlin android-databinding android-mvvm android-architecture-components
2019年5月7日androidx.lifecycle:*:2.2.0-alpha01发布,宣布:
此版本添加了新功能,增加了对Lifecycle和LiveData的Kotlin协程的支持。可以在此处找到有关它们的详细文档。
在文档中提到我可以得到LifecycleScope:
通过
lifecycle.coroutineScope或lifecycleOwner.lifecycleScope属性
但似乎我找不到它们。我目前的依赖是:
def lifecycle_ver = "2.2.0-alpha01"
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_ver"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_ver"
implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_ver"
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.2.1'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.2.1'
Run Code Online (Sandbox Code Playgroud)
可能是什么原因以及如何获得这些API?
在我看来,Kotlin 是零安全的。
代码 A 来自项目 Universal Android Music Player Sample,你可以在这里看到
val rootMediaId: LiveData<String>代码A中好像不是空安全的,可以给空字符串赋值rootMediaId,不知道为什么Android Studio可以编译这些代码,能告诉我吗?
我认为代码 B 是有信誉的代码。
代码 A
viewModel.rootMediaId.observe(this,
Observer<String> { rootMediaId ->
if (rootMediaId != null) {
navigateToMediaItem(rootMediaId)
}
})
class MainActivityViewModel(
private val musicServiceConnection: MusicServiceConnection
) : ViewModel() {
val rootMediaId: LiveData<String> =
Transformations.map(musicServiceConnection.isConnected) { isConnected ->
if (isConnected) {
musicServiceConnection.rootMediaId
} else {
null
}
}
...
}
Run Code Online (Sandbox Code Playgroud)
代码 B
class MainActivityViewModel(
private val musicServiceConnection: MusicServiceConnection
) : ViewModel() {
val …Run Code Online (Sandbox Code Playgroud)