在Compose for Desktop中如何监控网络连接状态并阻塞应用至恢复?
实现Compose Desktop的网络状态监听与阻塞弹窗
由于Compose Desktop无法使用Android的ConnectivityManager,我们可以基于Java/Kotlin标准库实现网络检测,再结合Compose组件完成阻塞式弹窗功能。
1. 基础网络连通性检测
利用InetAddress的isReachable方法检测网络连通性,选择高可用的公共IP(比如Google DNS 8.8.8.8)做验证:
private fun isNetworkAvailable(): Boolean { return try { // 设置3秒超时,避免过长等待影响体验 val targetAddress = InetAddress.getByName("8.8.8.8") targetAddress.isReachable(3000) } catch (e: IOException) { // 抛出IO异常说明网络不通 false } }
2. 阻塞式弹窗与持续监听
通过Compose的Dialog组件实现阻塞效果(禁止用户关闭弹窗或点击外部),配合LaunchedEffect启动后台协程持续检测网络状态:
@Composable fun MainScreen() { // 保存当前网络异常状态 var isNetworkDown by remember { mutableStateOf(!isNetworkAvailable()) } // 启动循环检测协程,每隔5秒检查一次 LaunchedEffect(Unit) { while (true) { // 切换到IO线程执行检测,避免阻塞UI isNetworkDown = withContext(Dispatchers.IO) { !isNetworkAvailable() } delay(5000) } } // 应用主内容区域 Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { Text("应用正常运行中") // 网络异常时显示阻塞弹窗 if (isNetworkDown) { Dialog( onDismissRequest = {}, // 空实现,禁止通过关闭按钮关闭 properties = DialogProperties( dismissOnBackPress = false, // 禁止返回键关闭 dismissOnClickOutside = false // 禁止点击外部关闭 ) ) { Surface( modifier = Modifier.width(320.dp).height(200.dp), shape = RoundedCornerShape(12.dp) ) { Column( Modifier.fillMaxSize().padding(24.dp), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center ) { Text("网络连接异常", style = MaterialTheme.typography.headlineSmall) Spacer(Modifier.height(16.dp)) Text("请检查网络设置后重试") Spacer(Modifier.height(16.dp)) Button(onClick = { // 手动触发一次网络检测 isNetworkDown = withContext(Dispatchers.IO) { !isNetworkAvailable() } }) { Text("重试") } } } } } } }
3. 优化建议
- 自定义检测地址:可以将检测地址改为你的业务服务器IP/域名,避免公共IP被地区屏蔽导致误判
- 增加容错机制:连续多次检测失败才判定网络断开,减少临时波动的影响:
private fun isNetworkAvailable(): Boolean { var retryCount = 0 val maxRetries = 2 while (retryCount <= maxRetries) { try { val targetAddress = InetAddress.getByName("your-server.com") if (targetAddress.isReachable(2000)) return true } catch (e: IOException) { retryCount++ kotlinx.coroutines.delay(500) } } return false } - 全局状态管理:如果需要在多个页面共享网络状态,可以用
StateFlow实现全局监听:
在组件中收集状态:object NetworkMonitor { private val _isNetworkAvailable = MutableStateFlow(isNetworkAvailable()) val isNetworkAvailable: StateFlow<Boolean> = _isNetworkAvailable.asStateFlow() init { CoroutineScope(Dispatchers.IO).launch { while (true) { _isNetworkAvailable.value = isNetworkAvailable() delay(5000) } } } private fun isNetworkAvailable(): Boolean { // 检测逻辑同前 } }val isOnline by NetworkMonitor.isNetworkAvailable.collectAsState()
内容的提问来源于stack exchange,提问作者Francisco Engenheiro
相关产品推荐
相关产品推荐

