首页 > 解决方案 > 如何返回/转换流来自 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
            }
        }
    }

我怎样才能转换BooleanFlow<Boolean>

如果您认为可以通过任何其他方式订阅网络上发生的更改,请告诉我。

感谢您的帮助和建议。R

标签: androidkotlinflowkotlin-coroutines

解决方案


StateFlow您不必使用 a或LiveDataa 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找到官方文档。


推荐阅读