【发布时间】:2020-06-27 16:51:32
【问题描述】:
我更改了问题标题,因为Kiskae provided 解决了更广泛的问题,这使得关于包装回调 API 的问题对于特定问题来说是不必要的。以前的问题标题是:
如何使用 Coroutines 将异步回调封装到挂起函数中?
我正在尝试将 Android 框架的 ConnectivityManager.NetworkCallback 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 BEFORE
[DefaultDispatcher-worker-1] registerNetworkCallback AFTER
不过,onAvailable 和 onLost 永远不会被调用。
参考文献
- 这是受到codelabs/building-kotlin-extensions-library/#4 的启发。有关示例应用程序,请参阅
FusedLocationProviderClient.awaitLastLocation()。
相关
【问题讨论】:
-
您是否添加了使用互联网的权限
-
是的,
<uses-permission android:name="android.permission.INTERNET" />在 AndroidManifest.xml 中。 -
听说当天的协程builder函数是
suspendCancellableCoroutine -
@EpicPandaForce 你有没有错过我在sn-p代码中使用了这个函数?
-
是的。不知道除了你需要
suspendCancellableCoroutine之外,还有什么问题,哎呀。
标签: android kotlin kotlin-coroutines suspend android-connectivitymanager