android - 如何在使用 ContentProvider 进行大量更改时暂停通知观察者

标签 android cursor observer-pattern android-contentprovider suspend

我有一个 ExpandableListView,它使用 SimpleCursorTreeAdapter,它使用 ContentProvider 返回的游标。这很好,因为它始终与数据保持同步,但有时我需要对数据库进行许多更改,以便在同一秒内多次重新查询游标。是否可以暂停 ContentObservers 的通知以避免不必要的重新查询?

最佳答案

一个可能的解决方案是修改内容提供者以允许暂停通知。要通知的 URI 被添加到队列中,直到禁用暂停。

private boolean suspendNotifications = false;
private LinkedList<Uri> suspendedNotifications = new LinkedList<Uri>();
private HashSet<Uri> suspendedNotificationsSet = new HashSet<Uri>();

    private void notifyChange(Uri uri) {
    if (suspendNotifications) {
        synchronized (suspendedNotificationsSet) { // Must be thread-safe
            if (suspendedNotificationsSet.contains(uri)) {
                // In case the URI is in the queue already, move it to the end.
                // This could lead to side effects because the order is changed
                // but we also reduce the number of outstanding notifications.
                suspendedNotifications.remove(uri); 
            }
            suspendedNotifications.add(uri);
            suspendedNotificationsSet.add(uri);
        }
    }
    else {
        getContext().getContentResolver().notifyChange(uri, null);
    }
}

private void notifyOutstandingChanges() {
    Uri uri;
    while ((uri = suspendedNotifications.poll()) != null) {
        getContext().getContentResolver().notifyChange(uri, null);
        suspendedNotificationsSet.remove(uri);
    }
}

private void setNotificationsSuspended(boolean suspended) {
    this.suspendNotifications = suspended;
    if (!suspended) notifyOutstandingChanges();
}

@Override
public Uri insert(Uri uri, ContentValues values) {
    ...
    notifyChange(uri);
    return newItemUri;
}

我不确定如何最好地启用/禁用暂停,但一种可能性是在 update() 方法中有一个特殊的 URI 来打开/关闭暂停(例如 content:///suspension):

@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
    switch (uriMatcher.match(uri)) {
    ...
    case SUSPEND:
        boolean enabled = values.getAsBoolean("enabled");
        setNotificationsSuspended(enabled);
        break;
    ... 
    }
}

对数据库进行更改的服务现在可以在 ContentProvider 启动时暂停它,并在它完成时禁用暂停。

关于android - 如何在使用 ContentProvider 进行大量更改时暂停通知观察者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4292182/

相关文章:

java.lang.错误: FATAL EXCEPTION Google Play Android 10

android - 创建一个游标指向一个数组

oracle - WHERE CURRENT OF 引发无效 rowid 错误

clojure - 如何以纯函数的方式实现观察者设计模式?

android - 如何在android中使用设备管理员应用程序阻止安装其他应用程序

正在进行的通话中的 Android 干扰

c++ - 具有不同通知的观察者模式

session - Magento 购物车 : Check for items empties cart

java - Android:角色显示为一个盒子

node.js - MongoDB 驱动程序 : MongoError: Cursor Not found, 游标 ID : 7820213409290816 in namespace: db_name. collection_name