延时源码:
//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 );
即可解决问题。