如何暂停通知观察员在使用的ContentProvider做了许多变化 [英] How to suspend notification to observers while doing many changes using a ContentProvider

查看:145
本文介绍了如何暂停通知观察员在使用的ContentProvider做了许多变化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用它利用ContentProvider的返回游标一个SimpleCursorTreeAdapter的ExpandableListView。这是细,因为它总是与数据同步保持,但有时我需要使光标在相同的第二重新查询多次做许多变化到数据库。是否有可能暂停ContentObservers的通知,以避免不必要的requerys?

I have an ExpandableListView that uses a SimpleCursorTreeAdapter which uses the cursors returned by a ContentProvider. This is fine as it always keeps in sync with the data but sometimes I need to do many changes to the database so that the cursor is requeried many times in the same second. Is it possible to suspend the notification of ContentObservers to avoid unnecessary requerys?

推荐答案

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

A possible solution is to modify the content provider to allow suspending notifications. URIs to be notified are added to a queue until suspension is disabled.

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;
}

我不知道如何最好地启用/禁用悬挂,但一种可能是有一个特别的URI其打开/关闭悬架(如内容://&LT;授权&GT; /悬浮液)在update()方法

I'm not sure how to best enable/disable suspension but one possibility would be to have a special URI which turns on/off suspension (e.g. content://<authority>/suspension) in the update() method:

@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,当它启动和禁用悬架,当它完成的服务。

The service that does the changes to the database can now suspend the ContentProvider when it starts and disable suspension when it finishes.

这篇关于如何暂停通知观察员在使用的ContentProvider做了许多变化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆