繁体   English   中英

在 Kotlin(Android) 中使用 Delegates.observable 和 StateFlow

[英]Using Delegates.observable with StateFlow in Kotlin(Android)

我有一个监控网络 state 的 class。 我正在使用 Flow 来收集网络 state 更新。 但是,我还需要保留一个选项来使用程序员可以“挂钩”的手动侦听器,以便能够接收网络更改。

我的代码很简单:

 private val networkTypeState = MutableStateFlow<NetworkState>(NetworkState.Unknown)
 val networkTypeAsFlow: StateFlow<NetworkState> by notifyDelegate(networkTypeState)

 private fun <T> notifyDelegate(init: T) =
    Delegates.observable(init) { prop, _, new ->
        Lg.i("notify subscribers of network update: ${prop.name} = $new")
        notifySubscribers()
    }

sealed class NetworkState {
    object Unknown: NetworkState()
    object Disconnected: NetworkState()
    data class Connected(val isCellularOn: Boolean, val isWifiOn: Boolean): NetworkState()
}

然后当我更新 state 时,例如:

networkTypeState.value = NetworkState.Disconnecteddelegates.observable不会被调用

值得注意的是,当我使用networkTypeAsFlow.collect {.. }时,效果很好,这意味着 - networkTypeAsFlow确实得到了更新,它只是不调用delegates.observable

Observable 委托监控属性本身的变化。 将 Observable 用于val属性是徒劳的,因为val属性永远不会设置为新值。 改变属性指向的 object 对属性委托是完全不可见的。

如果你想观察变化,你可以启动并收集:

private val networkTypeState = MutableStateFlow<NetworkState>(NetworkState.Unknown)
val networkTypeAsFlow: StateFlow<NetworkState> = networkTypeState

init {
    viewModelScope.launch {
        networkTypeAsFlow.collect { 
            Lg.i("notify subscribers of network update: $it")
            notifySubscribers()
        }
    }
}

这里的另一个好处是,无论网络notifySubscribers是从哪个线程更改的,都将始终从同一个调度程序调用 notifySubscribers。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM