You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xamarin-Android应用待机数小时后WiFi丢失且检测时冻结问题求助

解决Android应用待机后WiFi丢失与定时器冻结问题

嘿,这个问题在Android开发里挺常见的——系统的低功耗策略(比如Doze模式)和后台限制是罪魁祸首,普通定时器根本扛不住系统的“打压”,还容易把应用搞僵。咱们一步步来解决:

1. 换掉普通定时器,用WorkManager搞周期性检测

普通的Timer、Handler.postDelayed()在应用待机后,会被系统的Doze模式直接限制,要么任务不执行,要么占着CPU导致应用冻结。WorkManager是Jetpack官方推的后台任务工具,专门适配系统的低功耗策略,能保证任务在合适的时机跑起来,还不会被轻易杀死。

举个Kotlin的例子:

// 构建周期性任务请求,这里设为1小时检测一次,你可以按需调整
val wifiCheckRequest = PeriodicWorkRequestBuilder<WifiCheckWorker>(1, TimeUnit.HOURS)
    .setConstraints(Constraints.Builder()
        .setRequiredNetworkType(NetworkType.CONNECTED) // 只在有网络时执行,避免空跑
        .build())
    .build()

// 把任务丢进WorkManager队列
WorkManager.getInstance(context).enqueue(wifiCheckRequest)

// 对应的Worker类,负责检测WiFi状态
class WifiCheckWorker(context: Context, params: WorkerParameters) : Worker(context, params) {
    override fun doWork(): Result {
        val connectivityManager = applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        val activeNetwork = connectivityManager.activeNetwork
        val networkCapabilities = connectivityManager.getNetworkCapabilities(activeNetwork)
        
        // 判断当前是否是WiFi连接
        val isWifiConnected = networkCapabilities?.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) == true

        if (!isWifiConnected) {
            // WiFi丢了,这里可以发通知提醒用户,或者做其他处理
            // 注意:Android 10+ 不让后台自动连WiFi,得引导用户手动操作
            sendWifiLostAlert()
        }
        return Result.success()
    }

    private fun sendWifiLostAlert() {
        // 这里写构建通知的逻辑,比如用NotificationManager发送通知
    }
}

2. 用NetworkCallback实时监听WiFi状态,比轮询更高效

与其定时轮询,不如直接监听网络变化——Android 7.0+ 之后CONNECTIVITY_ACTION广播被限制,所以用ConnectivityManager.NetworkCallback是更合规的方式,能实时捕获WiFi连接丢失/恢复的事件,减少CPU消耗,也不会导致应用冻结。

示例代码:

val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val wifiCallback = object : ConnectivityManager.NetworkCallback() {
    override fun onLost(network: Network) {
        super.onLost(network)
        // 检查是否是WiFi连接丢失
        val currentNetwork = connectivityManager.activeNetwork
        val currentCapabilities = connectivityManager.getNetworkCapabilities(currentNetwork)
        if (currentCapabilities?.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) != true) {
            // 处理WiFi丢失逻辑,比如发通知
        }
    }

    override fun onAvailable(network: Network) {
        super.onAvailable(network)
        // WiFi重新连上了,可以做恢复操作
    }
}

// 注册回调,只监听WiFi类型的网络
connectivityManager.registerNetworkCallback(
    NetworkRequest.Builder()
        .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
        .build(),
    wifiCallback
)

记得在合适的时机(比如Activity销毁时)注销回调,避免内存泄漏。

3. 适配系统权限与电池优化

  • 首先在AndroidManifest.xml里加必要的权限:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<!-- Android 12+ 需要这个权限发通知 -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
  • 如果你的应用必须在待机时保持WiFi连接,可以引导用户把应用加入电池优化白名单,但尽量别这么做——会影响用户的续航体验,除非是核心功能必需。引导代码如下:
val intent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS).apply {
    data = Uri.parse("package:" + context.packageName)
}
context.startActivity(intent)

最后总结

核心思路就是跟着Android系统的规则走:用WorkManager处理后台周期性任务,用NetworkCallback实时监听网络变化,别用普通定时器硬刚系统的低功耗策略。这样既能解决WiFi丢失的检测问题,又不会让应用出现冻结的情况。

内容的提问来源于stack exchange,提问作者Luk4

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:02:45