我更改了问题标题,因为https://stackoverflow.com/a/60712092/356895是更广泛的问题的解决方案,这使得包装回调API的问题对于特定的问题来说是不必要的。前一个问题标题是:
如何使用Coroutines将异步回调包装为挂起函数?
我正在尝试将安卓框架的ConnectivityManager.NetworkCallback API (>= 21级)封装到一个暂停函数中,以促进同步API:
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
}当我调用isNetworkAvailable(NetworkCapabilities.TRANSPORT_WIFI)时,输出如下:
DefaultDispatcher-worker-1 registerNetworkCallback DefaultDispatcher-worker-1 registerNetworkCallback后
不过,onAvailable和onLost从来没有被调用过。
参考文献
FusedLocationProviderClient.awaitLastLocation()。相关
发布于 2020-03-16 19:25:18
您想要做的事情的相关API并不是异步的,因此不应该需要协同:
private fun ConnectivityManager.isNetworkAvailable(
vararg transportType: /* android.net.NetworkCapabilities.Transport */ Int)
: Boolean {
val network = getActiveNetwork()
val caps = getNetworkCapabilities(network)
return caps != null && transportType.all(caps::hasTransport)
}这只需要Manifest.permission.ACCESS_NETWORK_STATE。
如果要主动搜索具有所需功能的网络,则需要使用requestNetwork API。(和许可Manifest.permission.CHANGE_NETWORK_STATE)
https://stackoverflow.com/questions/60708291
复制相似问题