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

Android 14下WorkManager夜间网络请求异常:无主机地址关联

问题分析与解决方案

核心问题拆解

  1. WorkManager网络约束局限性:NetworkType.CONNECTED仅验证设备存在网络连接,不保证网络实际可访问互联网(比如Wi-Fi物理连接但路由器休眠、DNS缓存失效)。
  2. Android 14网络行为变化:系统对后台网络的休眠优化更严格,夜间Wi-Fi可能处于"假连接"状态(有连接标识但无实际数据通路)。
  3. 自定义NetworkStateTracker检查不充分:仅判断NET_CAPABILITY_INTERNET,该标记仅表示网络具备互联网能力,不代表实际连通。

具体解决方案

1. 升级WorkManager约束,使用更严格的网络验证

将WorkRequest的网络约束从CONNECTED改为UNMETERED(针对Wi-Fi场景),或结合Android 10+的NET_CAPABILITY_VALIDATED能力,确保网络已通过系统验证可访问:

val constraints = Constraints.Builder()
    // Wi-Fi场景优先使用UNMETERED
    .setRequiredNetworkType(NetworkType.UNMETERED)
    // 添加网络验证能力要求(Android 10+)
    .setRequiredNetworkCapabilities(
        NetworkCapabilities.Builder()
            .addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
            .build()
    )
    .build()

2. Worker内部添加实际网络连通性校验

不要依赖外部状态检查,在Worker执行请求前,做一次实际的域名解析或轻量请求验证,确保网络真的可用:

private fun isNetworkReachable(host: String = "script.googleapis.com"): Boolean {
    return try {
        // 尝试解析目标域名,超时设为3秒
        val address = InetAddress.getByName(host)
        address.isReachable(3000)
    } catch (e: IOException) {
        false
    }
}

// 在Worker的doWork()中使用
override fun doWork(): Result {
    if (!isNetworkReachable()) {
        // 网络不可用,返回重试
        return Result.retry()
    }
    // 执行实际请求逻辑
    // ...
}

3. 配置指数退避重试策略

默认的Result.retry()重试间隔过短,可能网络还未恢复。在WorkRequest中设置指数退避,让重试间隔随次数递增:

val request = OneTimeWorkRequestBuilder<ProgramWorker>()
    .setConstraints(constraints)
    // 指数退避:初始延迟1分钟,每次重试间隔翻倍,最大延迟1小时
    .setBackoffCriteria(BackoffPolicy.EXPONENTIAL, 1, TimeUnit.MINUTES)
    .setInputData(...)
    .build()

4. 适配Android 14 Wi-Fi休眠优化

  • 引导用户开启Wi-Fi休眠保持:设置 > 网络和互联网 > Wi-Fi > Wi-Fi偏好 > 睡眠期间保持Wi-Fi开启
  • 在Worker中主动请求活跃网络并绑定,确保请求使用的网络处于活跃状态:
override fun doWork(): Result {
    val connectivityManager = getSystemService(ConnectivityManager::class.java)
    val networkRequest = NetworkRequest.Builder()
        .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
        .addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
        .build()
    
    val networkCallback = object : ConnectivityManager.NetworkCallback() {
        override fun onAvailable(network: Network) {
            // 绑定到该活跃网络执行请求
            connectivityManager.bindProcessToNetwork(network)
            // 执行请求逻辑
            // ...
            connectivityManager.unregisterNetworkCallback(this)
        }
    }
    
    connectivityManager.requestNetwork(networkRequest, networkCallback)
    // 注:若使用CoroutineWorker,可改用异步逻辑避免阻塞
    // ...
}

5. 修复NetworkStateTracker的网络检查逻辑

更新网络状态判断,加入NET_CAPABILITY_VALIDATED(Android 10+),确保状态反映实际连通性:

private fun checkCurrentConnectivity(): Boolean {
    val network = connectivityManager.activeNetwork ?: return false
    val capabilities = connectivityManager.getNetworkCapabilities(network) ?: return false
    // 同时检查互联网能力和已验证状态
    return capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) &&
            capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
}

// 补充onCapabilitiesChanged的状态更新,实时同步网络验证状态
override fun onCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities) {
    val isConnected = networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) &&
            networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
    _networkState.value = isConnected
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 17:34:52