当PendingIntent不可用时,如何正确调用releaseNetworkRequest(PendingIntent)
我正尝试发起网络请求,因此构建了NetworkRequest和PendingIntent,代码如下:
ConnectivityManager conn_manager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE); NetworkRequest net_req; net_req = new NetworkRequest.Builder() .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR) //Data Network? .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) //Wifi .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) //This might be what need internet permis...
想咨询:当PendingIntent不可用时,应如何正确调用releaseNetworkRequest(PendingIntent)方法?
首先得明确一个核心点:ConnectivityManager.releaseNetworkRequest()需要和你调用requestNetwork()时传入的**同一个PendingIntent实例(或系统匹配的等价实例)**才能正确释放对应的网络请求。如果你的PendingIntent已经不可用(比如被主动取消、创建它的上下文已销毁,或者通过FLAG_NO_CREATE获取返回null),可以按以下步骤处理:
第一步:先验证PendingIntent的可用性
你可以用创建时的相同参数,加上PendingIntent.FLAG_NO_CREATE来检查实例是否还存在:// 假设你当初是创建的广播类型PendingIntent,替换成你实际的参数 PendingIntent checkIntent = PendingIntent.getBroadcast( getApplicationContext(), requestCode, // 和创建时一致的requestCode originalIntent, // 和创建时一致的Intent PendingIntent.FLAG_NO_CREATE | 你的原始flags // 保留原始flags,加上FLAG_NO_CREATE ); if (checkIntent == null) { // PendingIntent已经不可用了 }如果PendingIntent不可用,尝试重建等价实例来释放
因为PendingIntent是基于「内容匹配」的,只要你用和当初创建时完全一致的参数(上下文、requestCode、Intent内容、flags)重新创建,系统会返回和之前关联同一个网络请求的实例,然后用它调用releaseNetworkRequest()即可:// 重建和当初完全一致的PendingIntent PendingIntent rebuiltIntent = PendingIntent.getBroadcast( getApplicationContext(), requestCode, originalIntent, originalFlags // 和创建时完全相同的flags,比如FLAG_UPDATE_CURRENT等 ); // 调用释放方法 conn_manager.releaseNetworkRequest(rebuiltIntent);从根源避免这个问题的建议
最好的处理方式是提前避免PendingIntent不可用的场景:- 在组件的生命周期回调里主动释放:比如在Activity的
onDestroy()、Service的onDestroy()中,调用releaseNetworkRequest(),这时候PendingIntent还处于可用状态。 - 跟踪所有发起的网络请求对应的PendingIntent实例:用集合存储这些实例,在合适的时机统一释放,避免丢失引用。
- 在组件的生命周期回调里主动释放:比如在Activity的
另外补充一点:如果实在无法重建等价的PendingIntent,也不用太担心——当你的应用进程被杀死,或者网络请求超时/完成时,系统会自动回收对应的网络请求资源,不会造成永久的资源泄漏,但主动处理始终是更规范的做法。
内容的提问来源于stack exchange,提问作者JamisonMan111

