我在更新我的Android应用程序至API 28时,发现了 registerDefaultNetworkCallback 和registerNetworkCallback。
经过查看文档后,我无法找到注册“网络回调”和注册“默认网络回调”之间的区别。
什么情况下会使用哪个呢?
提前感谢 :)
我在更新我的Android应用程序至API 28时,发现了 registerDefaultNetworkCallback 和registerNetworkCallback。
经过查看文档后,我无法找到注册“网络回调”和注册“默认网络回调”之间的区别。
什么情况下会使用哪个呢?
提前感谢 :)
registerDefaultNetworkCallback
和registerNetworkCallback
之间的区别仅在于定制方面。registerDefaultNetworkCallback
(令人惊讶地)作为默认网络侦听器工作,而registerNetworkCallback
则更具可配置性。例如: val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val builder = NetworkRequest.Builder()
builder.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
val networkRequest = builder.build()
connectivityManager.registerNetworkCallback(networkRequest,
object : ConnectivityManager.NetworkCallback () {
override fun onAvailable(network: Network?) {
super.onAvailable(network)
Log.i("Test", "Network Available")
}
override fun onLost(network: Network?) {
super.onLost(network)
Log.i("Test", "Connection lost")
}
})
如果用户连接到蜂窝网络,onAvailable
将被调用(通过连接到 WiFi,它不会记录任何内容)。同样,当与蜂窝网络断开连接时,onLost
也是如此。
如果我们这样做:
connectivityManager.registerDefaultNetworkCallback(object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network?) {
super.onAvailable(network)
Log.i("Test", "Default -> Network Available")
}
override fun onLost(network: Network?) {
super.onLost(network)
Log.i("Test", "Default -> Connection lost")
}
})
这两个函数是在用户连接(或断开连接)到/从网络时作为默认回调函数。网络可以是WiFi或蜂窝网络。
这只是一些非常基本的示例。当设置capability
或transportType
时,NetworkRequest
可以具有许多配置选项。您可以在NetworkRequest的官方文档中了解更多信息。
registerNetworkCallback()
在API 21(Android 5.0,棒棒糖)中添加。它允许您监听满足某些传输类型(WiFi、蜂窝数据、蓝牙等)和能力(SMS、NOT_METERED
等)的网络变化。
registerDefaultNetworkCallback()
在API 24(Android 7.0,Nougat)中添加,当任何网络更改发生时使用您的回调,无论传输类型和能力如何。
registerNetworkCallback()
的示例。至少在我的情况下,我不关心过滤器,并希望我的代码适用于任何网络类型。这可以通过空Builder
对象实现:
/* Automatically start a download once an internet connection is established */
val cm = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
// could filter using .addCapability(int) or .addTransportType(int) on Builder
val networkChangeFilter = NetworkRequest.Builder().build()
cm.registerNetworkCallback(networkChangeFilter,
object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) = downloadStuff()
}
)
上面的代码等同于使用registerDefaultNetworkCallback()
的以下代码:
registerDefaultNetworkCallback()
:val cm = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
cm.registerDefaultNetworkCallback(
object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) = downloadStuff()
}
)
令人困惑的 NetworkRequest
实际上只是一种传输类型和功能的过滤器。
默认
版本的代码较少,但API级别较低,因此支持的手机较少(74%对94%)。由于我在 ConnectivityManagerCompat
中找不到向后兼容的API调用版本,所以如果21-23个API级别重要,请使用第一个版本。
registerDefaultNetworkCallback()
时,实际上是在告诉我有关标记为设备上所有应用程序将默认使用的“最佳”网络发生更改的信息。这就是为什么您不需要作为注册的一部分传递NetworkCapability
,因为默认网络由框架控制。
registerNetworkCallback()
类似,只是它不关心默认网络。您给它一些NetworkCapability
,并跟踪满足这些网络功能的任何网络,无论它们是否是默认网络。getDefaultNetwork()
来了解更多信息。registerDefaultNetworkCallback
,registerNetworkCallback
和default network
。ConnectivityManager.registerDefaultNetworkCallback()
是在 API 24 中添加的(如果与 Handler
一起使用,则为 API 26)。而 ConnectivityManager.registerNetworkCallback()
是在 API 21 中添加的(如果与 NetworkRequest
一起使用,则为 API 23)。registerNetworkCallback
的两个签名都需要一个 NetworkRequest
-- 区别在于回调类型 (NetworkCallback
vs PendingIntent
)。 - xjclclass NetworkMonitor(
private val application: Application,
val onChange: (isConnected: Boolean) -> Unit
) {
fun register() {
(application.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager).let { connectivityManager ->
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
registerAPI24AndAbove(connectivityManager)
} else {
registerAPI24Below(connectivityManager)
}
}
}
private fun registerAPI24AndAbove(connectivityManager: ConnectivityManager) {
connectivityManager.registerDefaultNetworkCallback(buildNetworkCallback())
}
private fun registerAPI24Below(connectivityManager: ConnectivityManager) {
NetworkRequest.Builder()
.addCapability(NetworkCapabilities.TRANSPORT_CELLULAR)
.addCapability(NetworkCapabilities.TRANSPORT_WIFI)
.build().let { networkRequest ->
connectivityManager.registerNetworkCallback(networkRequest, buildNetworkCallback())
}
}
private fun buildNetworkCallback(): ConnectivityManager.NetworkCallback {
return object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) {
this@NetworkMonitor.onChange(true)
}
override fun onLost(network: Network) {
this@NetworkMonitor.onChange(false)
}
}
}
}
请确保声明所需的权限!
Manifest.permission.ACCESS_NETWORK_STATE
然后在你的Application类中:
class MyApp : Application() {
override fun onCreate() {
super.onCreate()
NetworkMonitor(this) { isConnected ->
if (isConnected) {
// Do your thing
} else {
// Do your other thing
}
}.register()
}
}
onCreate
中吗? - xjclonAvailable
不会在主线程发生,因此任何 UI 更新都需要在runOnUiThread { /* code */ }
块中执行。 - xjcl