Domanda

Ho un ExpandableListView che utilizza una SimpleCursorTreeAdapter che utilizza i cursori restituiti da una ContentProvider. Questo va bene in quanto mantiene sempre in sincronia con i dati ma a volte ho bisogno di fare molti cambiamenti al database in modo che il cursore viene ripetizione molte volte nello stesso secondo. E 'possibile sospendere la notifica di ContentObservers al fine di evitare inutili requerys?

È stato utile?

Soluzione

Una possibile soluzione è quella di modificare il fornitore di contenuti per consentire la sospensione delle notifiche. URI da notificare vengono aggiunti a una coda fino a quando la sospensione è disabilitata.

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

Non sono sicuro di come meglio abilitare / disabilitare la sospensione, ma una possibilità sarebbe quella di avere uno speciale URI che accende / off sospensione (ad esempio il contenuto: // / sospensione) nel metodo 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;
    ... 
    }
}

Il servizio che fa i cambiamenti al database può ora sospendere la ContentProvider quando inizia e la sospensione disabilita quando finisce.

Altri suggerimenti

Si può utilizzare http: // sviluppatore .android.com / riferimento / android / widget di / BaseAdapter.html # unregisterDataSetObserver (android.database.DataSetObserver ) per annullare la registrazione i vostri ascoltatori e una volta che il vostro lavoro è pronto, registrare di nuovo loro? Suona come un AsyncTask per me.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top