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

WearOS应用:如何从Receiver访问并释放Activity创建的NetworkCallback?

WearOS 下载应用:全局管理NetworkCallback实现Wi-Fi按需释放

核心思路

用单例类统一管理NetworkCallback实例和下载任务计数,让Activity/Fragment、BroadcastReceiver都能访问,确保所有下载完成后才释放Wi-Fi回调,避免电量浪费。

1. 实现单例管理器类

创建WifiNetworkManager单例,封装Wi-Fi请求、回调释放和下载计数逻辑:

class WifiNetworkManager private constructor() {
    private var networkCallback: ConnectivityManager.NetworkCallback? = null
    private var connectivityManager: ConnectivityManager? = null
    // 原子计数器保证多线程安全
    private val activeDownloadCount = AtomicInteger(0)

    companion object {
        @Volatile
        private var INSTANCE: WifiNetworkManager? = null

        fun getInstance(): WifiNetworkManager {
            return INSTANCE ?: synchronized(this) {
                INSTANCE ?: WifiNetworkManager().also { INSTANCE = it }
            }
        }
    }

    // 请求Wi-Fi连接
    fun requestWifi(context: Context) {
        if (networkCallback != null) return

        val appContext = context.applicationContext
        connectivityManager = appContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        val networkRequest = NetworkRequest.Builder()
            .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
            .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
            .build()

        networkCallback = object : ConnectivityManager.NetworkCallback() {
            override fun onAvailable(network: Network) {
                super.onAvailable(network)
                connectivityManager?.bindProcessToNetwork(network)
            }

            override fun onLost(network: Network) {
                super.onLost(network)
                connectivityManager?.unbindProcessToNetwork()
            }
        }

        connectivityManager?.requestNetwork(networkRequest, networkCallback)
    }

    // 新增下载任务
    fun addDownloadTask() {
        activeDownloadCount.incrementAndGet()
    }

    // 完成单个下载任务,计数归零时释放回调
    fun finishDownloadTask() {
        if (activeDownloadCount.decrementAndGet() <= 0) {
            releaseCallback()
        }
    }

    // 强制释放回调(比如页面销毁时兜底)
    fun forceReleaseCallback() {
        releaseCallback()
    }

    private fun releaseCallback() {
        networkCallback?.let {
            connectivityManager?.unregisterNetworkCallback(it)
            connectivityManager?.unbindProcessToNetwork()
            networkCallback = null
            connectivityManager = null
            activeDownloadCount.set(0)
        }
    }
}

2. 在Activity/Fragment中调用

启动下载前初始化Wi-Fi请求,每个下载任务开始时标记任务:

// 页面初始化或准备下载时
WifiNetworkManager.getInstance().requestWifi(this)

// 每个下载任务启动时
WifiNetworkManager.getInstance().addDownloadTask()

// 单个下载任务完成(比如DownloadManager回调、OkHttp回调)
WifiNetworkManager.getInstance().finishDownloadTask()

// 页面销毁时兜底释放(防止下载异常导致计数未清零)
override fun onDestroy() {
    super.onDestroy()
    WifiNetworkManager.getInstance().forceReleaseCallback()
}

3. 在BroadcastReceiver中处理下载完成

如果用Receiver监听下载完成事件,直接调用任务完成方法:

class DownloadCompleteReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        // 处理下载完成的业务逻辑后
        WifiNetworkManager.getInstance().finishDownloadTask()
    }
}

关键注意点

  • 线程安全:用AtomicInteger管理下载计数,避免多线程环境下的计数错误。
  • 内存泄漏:单例中使用applicationContext,不持有Activity/Fragment的上下文。
  • 兜底释放:在页面销毁时强制释放回调,防止因下载任务异常导致Wi-Fi一直保持连接。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 03:01:11