1

許多變化我有一個使用它使用由ContentProvider的返回光標一個SimpleCursorTreeAdapter的ExpandableListView。這很好,因爲它始終與數據保持同步,但有時我需要對數據庫進行很多更改,以便在同一秒內多次重新查詢光標。是否可以暫停ContentObservers的通知以避免不必要的重複查詢?如何暫停通知觀察員而做使用的ContentProvider

回答

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

我不知道如何最好地啓用/禁用暫停,但一個可能性是有一個特殊的URI,其接通/關懸掛(如內容:// <權威> /暫停)在更新()方法:

@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

你可以使用http://developer.android.com/reference/android/widget/BaseAdapter.html#unregisterDataSetObserver(android.database.DataSetObserver)來註銷您的聽衆和一旦你的工作已就緒,重新註冊?聽起來像一個AsyncTask給我。

+0

這是不可能的。聽衆可以在任何地方,應用程序可以處於任何狀態。對數據庫的更改是在遠程服務中完成的。我也不認爲有可能取消註冊SimpleCursorTreeAdapter的觀察者,這意味着我必須創建一個自定義適配器。 – Tom 2010-11-28 11:37:13