如何使用协程将异步回调包装到暂停函数中?

问题描述 投票:0回答:1

[我正在尝试将Android框架的ConnectivityManager.NetworkCallback API(> = SDK级别21)包装到一个暂停函数中,以促进同步API:

ConnectivityManager.NetworkCallback

当我呼叫private suspend fun ConnectivityManager.isNetworkAvailable( vararg transportType: /* android.net.NetworkCapabilities.Transport */ Int) : Boolean { val isAvailable = suspendCancellableCoroutine<Boolean> { continuation -> val builder = NetworkRequest.Builder() transportType.forEach { builder.addCapability(it) } val networkRequest = builder.build() val networkCallback = object : ConnectivityManager.NetworkCallback() { override fun onAvailable(network: Network) { super.onAvailable(network) Log.d(javaClass.simpleName, "[${Thread.currentThread().name}] onAvailable") continuation.resume(true) unregisterNetworkCallback(this) } override fun onLost(network: Network) { super.onLost(network) Log.d(javaClass.simpleName, "[${Thread.currentThread().name}] onLost") continuation.resume(false) unregisterNetworkCallback(this) } } Log.d(javaClass.simpleName, "[${Thread.currentThread().name}] registerNetworkCallback BEFORE") registerNetworkCallback(networkRequest, networkCallback) Log.d(javaClass.simpleName, "[${Thread.currentThread().name}] registerNetworkCallback AFTER") } Log.d(javaClass.simpleName, "[${Thread.currentThread().name}] return isAvailable BEFORE") return isAvailable } 时,将输出以下内容:

[DefaultDispatcher-worker-1] registerNetworkCallback之前[DefaultDispatcher-worker-1] registerNetworkCallback AFTER

不过isNetworkAvailable(NetworkCapabilities.TRANSPORT_WIFI)onAvailable从未被调用。

参考

相关

android kotlin kotlin-coroutines suspend android-connectivitymanager
1个回答
0
投票

Callbacks and Kotlin Flows API观察到更改到网络状态,而不是网络状态,因为它处于当前状态。您需要使用Cancellation in coroutines API来检索满足指定要求的网络。

另外,我建议使用registerNetworkCallback的任何函数的范围都应尽可能小,以将异常封装到实际执行的操作中。类似于:

requestNetwork

如果您想为requestNetwork编写与协程兼容的API,您可能需要研究suspendCancellableCoroutine API,因为它是实时资源。

© www.soinside.com 2019 - 2024. All rights reserved.