我有一个 ExpandableListView,它使用一个 SimpleCursorTreeAdapter,它使用 ContentProvider 返回的游标。这很好,因为它始终与数据保持同步,但有时我需要对数据库进行许多更改,以便在同一秒内多次请求游标。是否可以暂停 ContentObservers 的通知以避免不必要的重新查询?
问问题
1423 次
2 回答
1
一种可能的解决方案是修改内容提供程序以允许暂停通知。要通知的 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://<authority>/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 启动时暂停它,并在它完成时禁用暂停。
于 2010-12-12T12:02:32.137 回答
0
您可以使用http://developer.android.com/reference/android/widget/BaseAdapter.html#unregisterDataSetObserver(android.database.DataSetObserver ) 取消注册您的听众,一旦您的工作准备就绪,再次注册?对我来说听起来像是一个 AsyncTask。
于 2010-11-27T17:54:57.877 回答