网络状态监听 → ConnectivityManager + Flow
老写法(Java + BroadcastReceiver)
java
public class NetworkReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager cm = (ConnectivityManager)
context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = cm.getActiveNetworkInfo();
boolean isConnected = info != null && info.isConnected();
updateNetworkState(isConnected);
}
}
// 注册
IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(new NetworkReceiver(), filter);
问题在哪里
NetworkInfo 已废弃(API 29+)。广播接收必须手动注册/解注册,生命周期管理容易泄漏。只能拿到"是否连接",具体网络类型获取麻烦。
新写法(ConnectivityManager + Flow)
kotlin
class NetworkMonitor(context: Context) {
private val connectivityManager =
context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val isConnected: Flow<Boolean> = callbackFlow {
val callback = object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) {
trySend(true)
}
override fun onLost(network: Network) {
trySend(false)
}
}
val request = NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.build()
connectivityManager.registerNetworkCallback(request, callback)
// 发送当前状态
val currentNetwork = connectivityManager.activeNetwork
val capabilities = connectivityManager.getNetworkCapabilities(currentNetwork)
trySend(capabilities?.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) == true)
awaitClose {
connectivityManager.unregisterNetworkCallback(callback)
}
}
}
// 使用
viewModelScope.launch {
networkMonitor.isConnected.collect { connected ->
tvStatus.text = if (connected) "已连接" else "无网络"
}
}
一句话注意
callbackFlow 是把回调 API 转为 Flow 的标准方式。trySend 在 Flow 里发射元素,awaitClose 在 Flow 被取消时自动执行清理逻辑(解注册 callback),不需要手动管理生命周期。
NetworkRequest.Builder().addCapability() 可以精确过滤网络类型------NET_CAPABILITY_INTERNET 表示该网络能访问互联网,TRANSPORT_WIFI 限制只监听 WiFi。addTransportType 也可以在 Builder 上链式调用组合多个条件。
Java Android 老项目迁移系列,持续更新中。