Android NetworkCallback网络状态监听无回调问题排查
Android 网络状态监听无回调问题解决方案
问题背景
开发Android网络状态监听示例应用时,参考官方文档实现了ConnectivityManager.NetworkCallback监听逻辑,出现以下异常:
- 设备已联网状态启动应用:onAvailable --- CALLED、onCapabilitiesChanged --- CALLED、onLost --- CALLED日志均可正常输出,回调触发符合预期
- 设备断网状态启动应用:启动时无任何日志输出,后续手动开启网络连接也不会触发任何回调
现有实现代码
MainActivity.kt
package me.soft.network import android.net.ConnectivityManager import android.net.Network import android.net.NetworkCapabilities import android.net.NetworkRequest import androidx.appcompat.app.AppCompatActivity import android.os.Bundle class MainActivity : AppCompatActivity() { lateinit var networkRequest: NetworkRequest private val networkCallback = object : ConnectivityManager.NetworkCallback() { // 网络可用 override fun onAvailable(network: Network) { super.onAvailable(network) println("onAvailable --- CALLED") } // 网络能力变更 override fun onCapabilitiesChanged( network: Network, networkCapabilities: NetworkCapabilities ) { super.onCapabilitiesChanged(network, networkCapabilities) val unmetered = networkCapabilities.hasCapability(NetworkCapabilities. NET_CAPABILITY_NOT_METERED) println("onCapabilitiesChanged --- CALLED") } // 网络连接丢失 override fun onLost(network: Network) { super.onLost(network) println("onLost --- CALLED") } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) networkRequest = NetworkRequest.Builder() .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR) .build() val connectivityManager = getSystemService(ConnectivityManager::class.java) as ConnectivityManager connectivityManager.requestNetwork(networkRequest, networkCallback) } }
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="me.soft.network"> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.INTERNET" /> <application android:allowBackup="true" android:dataExtractionRules="@xml/data_extraction_rules" android:fullBackupContent="@xml/backup_rules" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.NetWork" tools:targetApi="31"> <activity android:name=".MainActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
错误原因
- API误用:代码中调用的
requestNetwork()方法设计目标是主动向系统申请建立一条符合NetworkRequest规则的网络连接,属于主动发起网络请求的API,不是用于被动监听全局网络状态的API。当启动应用时无可用网络,该方法不会持续驻留等待后续网络连接,因此后续联网时不会触发回调。 - 缺少回调反注册逻辑:当前代码仅在
onCreate中注册回调,未在页面销毁时反注册,会造成内存泄漏,极端场景下会触发崩溃。 - 代码中
NetworkCapabilities. NET_CAPABILITY_NOT_METERED存在多余空格,虽不影响编译,但属于不规范写法。
修正方案
- 将
requestNetwork()替换为专门用于网络状态监听的registerNetworkCallback()方法,该方法会持续监听符合规则的网络状态变化,不受启动时网络状态影响。 - 在
onDestroy生命周期中调用unregisterNetworkCallback()反注册回调,避免内存泄漏。 - 修正代码中的多余空格问题。
修正后核心代码
class MainActivity : AppCompatActivity() { private lateinit var networkRequest: NetworkRequest private lateinit var connectivityManager: ConnectivityManager private val networkCallback = object : ConnectivityManager.NetworkCallback() { override fun onAvailable(network: Network) { super.onAvailable(network) println("onAvailable --- CALLED") } override fun onCapabilitiesChanged( network: Network, networkCapabilities: NetworkCapabilities ) { super.onCapabilitiesChanged(network, networkCapabilities) val unmetered = networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED) println("onCapabilitiesChanged --- CALLED, unmetered: $unmetered") } override fun onLost(network: Network) { super.onLost(network) println("onLost --- CALLED") } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) networkRequest = NetworkRequest.Builder() .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR) .build() connectivityManager = getSystemService(ConnectivityManager::class.java) // 替换为注册网络监听的API connectivityManager.registerNetworkCallback(networkRequest, networkCallback) } override fun onDestroy() { // 反注册回调避免内存泄漏 connectivityManager.unregisterNetworkCallback(networkCallback) super.onDestroy() } }
可选优化
如果应用的最低支持版本为Android 7.0(API 24)及以上,可以直接使用registerDefaultNetworkCallback()方法,无需手动构建NetworkRequest,会自动监听系统当前默认的活跃网络,代码更简洁:
// 替换registerNetworkCallback即可,不需要提前构建networkRequest connectivityManager.registerDefaultNetworkCallback(networkCallback)
内容的提问来源于stack exchange,提问作者Michel
相关产品推荐
相关产品推荐

