我更改了问题标题,因为Kiskae 为更广泛的问题提供了解决方案,这使得关于包装回调 API 的问题对于特定问题来说是不必要的。以前的问题标题是:
如何使用协程将异步回调包装到挂起函数中?
我正在尝试将ConnectivityManager.NetworkCallback
Android 框架的 API(>= SDK 级别 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
andonLost
永远不会被调用。
参考
- 这是受到codelabs/building-kotlin-extensions-library/#4 的启发。请参阅
FusedLocationProviderClient.awaitLastLocation()
示例应用程序。