解决Android11APP在后台时ContentObserver.onChange延时10秒的问题

延时源码:

//services/core/java/com/android/server/content/ContentService.java
public void dispatch() {
            for (int i = 0; i < collected.size(); i++) {
                final Key key = collected.keyAt(i);
                final List<Uri> value = collected.valueAt(i);

                final Runnable task = () -> {
                    try {
                        key.observer.onChangeEtc(key.selfChange,
                                value.toArray(new Uri[value.size()]), key.flags, key.userId);
                    } catch (RemoteException ignored) {
                    }
                };

                // Immediately dispatch notifications to foreground apps that
                // are important to the user; all other background observers are
                // delayed to avoid stampeding
                final boolean noDelay = (key.flags & ContentResolver.NOTIFY_NO_DELAY) != 0;
                final int procState = LocalServices.getService(ActivityManagerInternal.class)
                        .getUidProcessState(key.uid);
                if (procState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND || noDelay) {
                    task.run();
                } else {
                    BackgroundThread.getHandler().postDelayed(task, BACKGROUND_OBSERVER_DELAY);
                }
            }
        }

可以修改源码,去掉noDelay 的判断

不想修改源码的可以根据此行来修改:

final boolean noDelay = (key.flags & ContentResolver.NOTIFY_NO_DELAY) != 0;

此处flags就是

ContentResolver.notifyChange(uri, null, flags);

所以不想修改源如果是自己的Provider的话可以在通知的时间加上flags:ContentResolver.NOTIFY_NO_DELAY

但是在android/content/ContentResolver.java中,NOTIFY_NO_DELAY是隐藏API

/**
 * Flag for {@link #notifyChange(Uri, ContentObserver, int)}: typically set
 * by a {@link ContentProvider} to indicate that this notification should
 * not be subject to any delays when dispatching to apps running in the
 * background.
 * <p>
 * Using this flag may negatively impact system health and performance, and
 * should be used sparingly.
 *
 * @hide
 */
public static final int NOTIFY_NO_DELAY = 1 << 15;

 可以自己直接定义一个,我的最终代码是:

private final int NOTIFY_NO_DELAY = 1<<15;
getContext().getContentResolver().notifyChange(uri, null, NOTIFY_NO_DELAY );

即可解决问题。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值