[我正在尝试将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
从未被调用。
onLost
的启发。有关示例应用程序,请参见codelabs/building-kotlin-extensions-library/#4。FusedLocationProviderClient.awaitLastLocation()
FusedLocationProviderClient.awaitLastLocation()
Callbacks and Kotlin Flows API观察到更改到网络状态,而不是网络状态,因为它处于当前状态。您需要使用Cancellation in coroutines API来检索满足指定要求的网络。
另外,我建议使用registerNetworkCallback
的任何函数的范围都应尽可能小,以将异常封装到实际执行的操作中。类似于:
requestNetwork
如果您想为requestNetwork
编写与协程兼容的API,您可能需要研究suspendCancellableCoroutine
API,因为它是实时资源。