android - 如何返回/转换流来自 Kotlin Coroutines 中的布尔值?
问题描述
我有一个 Android 库,我正在其中监听网络变化,我想做的是,使用流/启动协程观察这些变化
这是我的 NetworkReceiver,它让我知道连接何时发生变化
我采用了一个变量,该变量在库中isNetworkConnectionActive
设置为 false,init
并根据网络更改在以下函数中设置为 true false
class ConnectionChangeReceiver: BroadcastReceiver() {
override fun onReceive(context: Context?, p1: Intent?) {
if(isNetworkConnectionActive(context)) {
OfflineDataLibrary.isNetworkConnectionActive = true
Toast.makeText(context, "isNetworkConnectionActive - YES", Toast.LENGTH_LONG).show()
} else {
OfflineDataLibrary.isNetworkConnectionActive = false
Toast.makeText(context, "isNetworkConnectionActive - NO", Toast.LENGTH_LONG).show()
}
}
fun isNetworkConnectionActive(context: Context?): Boolean {
val connectivityManager: ConnectivityManager = context?.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
var isConnectionActive = false
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val nw = connectivityManager.activeNetwork ?: return false
val actNw = connectivityManager.getNetworkCapabilities(nw) ?: return false
return when {
actNw.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
actNw.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true
else -> false
}
} else {
val nwInfo = connectivityManager.activeNetworkInfo ?: return false
return nwInfo.isConnected
}
}
}
OfflineDataLibrary 有isNetworkConnectionActive
object OfflineDataLibrary {
lateinit var context: Context
var isNetworkConnectionActive: Boolean = false
fun init(ctx: Context) {
context = ctx.applicationContext
val offlineDataChangeListener = OfflineDataChangeListener()
offlineDataChangeListener.observeOfflineDataChanges()
}
}
isNetworkConnectionActive
现在我想使用****收听变量上发生的变化,Flow
我有一个类型不匹配,我想返回布尔值但我正在返回布尔值。***
fun getNetworkAvailability(): Flow<Boolean> {
return OfflineDataLibrary.isNetworkConnectionActive
}
我可以访问上述功能并听取这样的变化
fun getIsNetworkAvailable() {
launch {
OfflineDatabaseManager.getInstance(app.applicationContext).getNetworkAvailability().collect {
//DO something
}
}
}
我怎样才能转换Boolean
为Flow<Boolean>
?
如果您认为可以通过任何其他方式订阅网络上发生的更改,请告诉我。
感谢您的帮助和建议。R
解决方案
StateFlow
您不必使用 a或LiveData
a ConflatedChannel
,甚至不必将 a 转换Channel
为 a Flow
:
class ConnectionChangeReceiver: BroadcastReceiver() {
private val _networkConnectionActivated = MutableStateFlow(false) //An initial value is required
val networkConnectionActivated: StateFlow<Boolean>
get() = _networkConnectionActivated
override fun onReceive(context: Context?, p1: Intent?) {
_networkConnectionActivated.value = isNetworkConnectionActive(context)
}
fun isNetworkConnectionActive(context: Context?): Boolean {
val connectivityManager: ConnectivityManager = context?.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
var isConnectionActive = false
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val nw = connectivityManager.activeNetwork ?: return false
val actNw = connectivityManager.getNetworkCapabilities(nw) ?: return false
return when {
actNw.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
actNw.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true
else -> false
}
} else {
val nwInfo = connectivityManager.activeNetworkInfo ?: return false
return nwInfo.isConnected
}
}
}
你所要做的就是从课堂之外收集它的价值。请记住,它是合并的,因此在其值更改之前不会通知观察者:
myConnectionChangeReceiver.networkConnectionActivated
.collect { isNetworkConnectionActive ->
//Do something here
}
不要忘记在需要时通过取消所有正在运行的协程来停止所有观察者。
你可以在这里StateFlow
找到官方文档。
推荐阅读
- java - 在 Linux VM (Red hat 6.5) 中为 jvisualvm 显示 env var
- kubernetes - Kubernetes 上的 Keycloak 集群生产设置 - Google K8S Engine (GKE)
- android - 如何使用样式全局更改 AlertDialog 上的按钮文本颜色?
- sql - 按顺序执行查询
- python - 在导入的函数中修改变量
- powershell - 使用 PowerShell 仅远程终止特定的命令提示符进程
- javascript - How to look up data from an ul li?
- excel - Excel VBA 宏将复制一系列单元格并粘贴到另一个工作簿
- angular - Angular form not sending data
- unit-testing - vuetify : cannot trigger click on radio button