如何在 Android 中监听网络连接状态的变化?
解读
国内面试中,这道题几乎必问,因为它同时考察“系统广播机制”“权限模型”“生命周期感知”“省电合规”四个维度。面试官想确认:
- 你是否只会已被废弃的静态广播;
- 能否在 Android 8.0 之后用官方推荐方式存活;
- 是否了解国产 ROM 对后台广播的额外限制;
- 能否给出“无后台常驻、无耗电”的完整方案。
回答时务必先讲“合规”,再讲“实现”,最后给出“性能与兼容”细节,否则会被追问“用户杀进程后你还能收到吗?”
知识点
- 系统广播:ConnectivityManager.CONNECTIVITY_ACTION 在 7.0 之后仅限动态注册;静态广播无法接收。
- 权限:Android 10- 只需 ACCESS_NETWORK_STATE;Android 11+ 若需判断“真实上网能力”必须追加 ACCESS_WIFI_STATE 与 INTERNET。
- 生命周期感知:推荐在 Activity/Fragment 或 LifecycleService 中注册,退出即注销,防止内存泄漏。
- 国产 ROM 限制:小米、华为、OPPO 对后台广播有额外省电拦截,需引导用户手动关闭“省电优化”或改用前台 Service+通知。
- 精准判断:仅监听广播只能拿到“连接类型”,需主动调用 ConnectivityManager.getNetworkCapabilities() 判断 NET_CAPABILITY_VALIDATED 才能确认“可上网”。
- 省电替代:Jetpack WorkManager 2.7+ 提供 NetworkType.CONNECTED 约束,可周期任务代替实时监听;对实时性要求不高场景优先使用。
- 折叠屏/多窗口:监听 NetworkCallback 时需传入对应 LifecycleOwner,防止屏幕旋转后重复注册导致泄漏。
答案
分三步给出“面试级”标准答案,可直接背诵:
第一步:声明权限
AndroidManifest.xml 中仅保留最小权限
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
若需检测“是否真正连网”,再追加 INTERNET 权限即可。
第二步:动态注册 NetworkCallback(API 21+ 统一方案)
class NetworkMonitor(private val context: Application) : DefaultLifecycleObserver {
private val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
private val validNetwork = MutableStateFlow(false)
private val callback = object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) {
val capabilities = cm.getNetworkCapabilities(network)
val validated = capabilities?.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED) == true
validNetwork.value = validated
}
override fun onLost(network: Network) {
validNetwork.value = false
}
}
fun observe(): StateFlow<Boolean> = validNetwork.asStateFlow()
override fun onCreate(owner: LifecycleOwner) {
val request = NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.build()
cm.registerNetworkCallback(request, callback)
}
override fun onDestroy(owner: LifecycleOwner) {
cm.unregisterNetworkCallback(callback)
}
}
在 Application 的 onCreate() 中
ProcessLifecycleOwner.get().lifecycle.addObserver(NetworkMonitor(this))
即可实现“全局唯一、生命周期感知、无后台耗电”的监听。
第三步:国产 ROM 兼容
若需要“被用户强杀后仍能恢复监听”,将 NetworkMonitor 移至前台 Service(startForeground)并在通知栏常驻“网络守护”通知,同时在设置页引导用户关闭电池优化,满足国内厂商后台存活要求。
拓展思考
- 实时性 vs 省电:如果业务只是“上传日志”,用 WorkManager 的 NetworkType.CONNECTED 即可,无需常驻监听。
- 多网络并发:Android 9+ 支持双 Wi-Fi、双蜂窝,NetworkCallback 会回调多次,需以“是否具备 NET_CAPABILITY_VALIDATED”为准,而不是简单计数。
- 安全合规:Android 13 引入 NEARBY_WIFI_DEVICES 权限,若监听 Wi-Fi 状态变更需动态申请,避免被应用商店下架。
- 单元测试:使用 androidx.arch.core.executor.testing.InstantTaskExecutorRule + Turbine 可对 StateFlow 进行虚拟网络切换测试,无需真机。