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

Jetpack Compose中ContentResolver.addStatusChangeListener不生效问题

解决Jetpack Compose中ContentResolver.addStatusChangeListener不触发的问题

核心原因及对应解决方案

1. Composable生命周期与Activity生命周期不匹配

传统UI中,监听绑定的是Activity的onResume/onPause生命周期,只要Activity处于前台,监听就会持续生效。但你当前的SyncStatusManager是绑定到单个Composable的生命周期,一旦该Composable因页面切换、条件渲染被移除,DisposableEffect的onDispose会立即取消监听,导致后续同步事件无法触发。

修复代码:
将监听逻辑绑定到Activity的生命周期,通过LocalLifecycleOwner实现和传统UI一致的行为:

@Composable
fun SyncStatusManager(
    onSyncEvent: (count: Int) -> Unit
) {
    val lifecycleOwner = LocalLifecycleOwner.current
    val currentOnSyncEvent by rememberUpdatedState(onSyncEvent)
    
    DisposableEffect(lifecycleOwner) {
        val lifecycleObserver = object : DefaultLifecycleObserver {
            private var syncStatusHandle: Any? = null
            
            override fun onResume(owner: LifecycleOwner) {
                super.onResume(owner)
                syncStatusHandle = ContentResolver.addStatusChangeListener(
                    ContentResolver.SYNC_OBSERVER_TYPE_ACTIVE or ContentResolver.SYNC_OBSERVER_TYPE_PENDING
                ) {
                    currentOnSyncEvent(it)
                }
            }
            
            override fun onPause(owner: LifecycleOwner) {
                super.onPause(owner)
                syncStatusHandle?.let {
                    ContentResolver.removeStatusChangeListener(it)
                    syncStatusHandle = null
                }
            }
        }
        
        lifecycleOwner.lifecycle.addObserver(lifecycleObserver)
        
        onDispose {
            lifecycleOwner.lifecycle.removeObserver(lifecycleObserver)
        }
    }
}

2. 检查Composable的存在性

如果SyncStatusManager嵌套在if/when等条件渲染分支中,当条件不满足时,该Composable会从布局树中被移除,监听也会被自动取消。

解决方法:
将SyncStatusManager放置在Activity根Composable、导航宿主父节点等始终存在的布局节点中,避免因局部布局变化导致监听丢失。

3. 验证回调线程兼容性

ContentResolver的同步回调默认运行在主线程,但如果你的业务逻辑涉及跨线程操作,需确保回调在主线程触发Compose状态更新:

val mainHandler = remember { Handler(Looper.getMainLooper()) }
syncStatusHandle = ContentResolver.addStatusChangeListener(...) { count ->
    mainHandler.post {
        currentOnSyncEvent(count)
    }
}

4. 二次确认权限配置

即使你已授予权限,仍需检查Manifest声明是否完整:

<uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
<!-- Android 10+ 额外需要 -->
<uses-permission android:name="android.permission.ACCESS_SYNC_STATS" />

Android 13及以上版本部分同步权限需运行时申请,确保已通过ActivityResultContracts.RequestPermission完成权限申请流程。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 10:51:10