Как приостановить уведомление наблюдателей при внесении множества изменений с помощью ContentProvider - PullRequest
1 голос
/ 27 ноября 2010

У меня есть ExpandableListView, который использует SimpleCursorTreeAdapter, который использует курсоры, возвращаемые ContentProvider.Это хорошо, так как он всегда синхронизируется с данными, но иногда мне нужно внести много изменений в базу данных, чтобы курсор запрашивался много раз за одну секунду.Можно ли приостановить уведомление ContentObservers, чтобы избежать ненужных запросов?

Ответы [ 2 ]

1 голос
/ 12 декабря 2010

Возможным решением является изменение поставщика контента, чтобы разрешить приостановку уведомлений.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;
}

Я не уверен, как лучше включить / отключить приостановку, но одной из возможных причин будет специальный URI, который включает / выключаетприостановка (например, содержимое: // / подвеска) в методе update ():

@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 при запуске и отключить приостановку приэто заканчивается.

0 голосов
/ 27 ноября 2010

Можете ли вы использовать http://developer.android.com/reference/android/widget/BaseAdapter.html#unregisterDataSetObserver(android.database.DataSetObserver), чтобы отменить регистрацию ваших слушателей, и как только ваша работа будет готова, зарегистрируйте их снова?Для меня это звучит как AsyncTask.

...