データベースの傍受.データベースは1回notify、Activityは複数回受信します

5189 ワード

今日のプロジェクトでバグが見つかりました.
 
(1)uriデータベースに更新がある場合、データベース層DataServiceからアプリケーション層に通知し、notifyChangeを呼び出す.
mContext.getContentResolver().notifyChange(uri, null);
 
(2)ActivityにクラスDataListenerがある
 1   class DataListener extends ContentObserver

 2     {

 3 

 4         public DataListener(Handler handler)

 5         {

 6             super(handler);

 7             // TODO Auto-generated constructor stub

 8         }

 9 

10         @Override

11         public void onChange(boolean selfChange)

12         {

13             try

14             {

15                 List<ContactDataItem> contactList = DataService.getInstance().getDao(ContactDataItem.class).queryForAll();

16                 Log.d(LogConfig.CONTRACTS_TAG, "data change");

17                 mNeedRefreshContactList = true;

18                 mContactsAdapter.setContactList(contactList);

19                 notifyDataSetChanged();

20             }

21             catch (SQLException e)

22             {

23                 // TODO Auto-generated catch block

24                 e.printStackTrace();

25             }

26         }

27     }

 
Activityで、データベースのリスニングを登録
mDataListener = new DataListener(new Handler(this.getMainLooper()));
mContext.getContentResolver().registerContentObserver(uri, false, mDataListener);
 
(3)後ほど,logでDataServiceから通知があったことが分かった.
==DataService== notifyChange  Uri  content://test/data/contact
しかし、Activityでは、以下のログの出現回数が増加しています.
Log.d(LogConfig.CONTRACTS_TAG, "data change");

1回目のページが1回、2回目のページが2回、ページも2回リフレッシュされます.
 
(4)後で低レベルのエラーであることを発見し、インタフェースを出る時にリスニングをキャンセルしなかった:
  mContext.getContentResolver().unregisterContentObserver(mDataListener);
 
 
 
 
ContentObserverメソッドの登録/登録解除、抽象クラスContentResolverクラスのメソッドのプロトタイプは次のとおりです.
 
    public final void registerContentObserver(Uri uri, boolean notifyForDescendents, ContentObserver observer)
機能:指定したUriにContentObserver派生クラスインスタンスを登録し、指定したUriが変更された場合、インスタンスオブジェクトをコールバックして処理します.
パラメータ:uriが観察する必要があるUri(UriMatcherに登録する必要があります.そうしないと、このUriも意味がありません)
observer ContentObserverの派生クラスインスタンス
notifyForDescentsはfalseで正確な一致を表します.すなわち、Uriのみが一致します.
trueには、派生するUriと同時に一致することができることを示します.たとえば、次のようになります.
UriMatcherに登録されているUriには、次のタイプがあるとします.
                                1 、content://com.qin.cb/student(学生)
                                2 、content://com.qin.cb/student/# 
                                3、 content://com.qin.cb/student/schoolchild(小学生、派生のUri)
現在観察すべきUriはcontent://com.qin.cb/student、データが変化した場合のUriはcontent://com.qin.cb/student/schoolchild
notifyForDescentsがfalseの場合、ContentObserverは傍受できません.
notifyForDescentsがtureの場合、Uriのデータベースの変化をキャプチャできます.