Android数据库数据变更监听,Android数据库内容变更的监听

首先介绍内容监测的基本模式

基于uri的内容监测的基本模式被android.content.ContentResolver实现。

它为基于Uri的内容监测的提供了一个平台。(其实如果有必要,我们可以自己实现一个)

ContentResolver为此提供了三个方法:

注册监听器到某个uri

public final void registerContentObserver (Uri uri, boolean notifyForDescendents, ContentObserver observer)

Register an observer class that gets callbacks when data identified by a given content URI changes.

Parameters

uri     The URI to watch for changes. This can be a specific row URI, or a base URI for a whole class of content.

notifyForDescendents     If true changes to URIs beginning with uri will also cause notifications to be sent.

If false only changes to the exact URI specified by uri will cause notifications to be sent.

If true, than any URI values at or below the specified URI will also trigger a match.

observer     The object that receives callbacks when changes occur.

取消被注册的监听器

public final void unregisterContentObserver (ContentObserver observer)

Unregisters a change observer.

参数

observer     The previously registered observer that is no longer needed.

通知所有注册到uri的监听器,告诉他们内容发生了改变。

public void notifyChange(Uri uri, ContentObserver observer)

Notify registered observers that a row was updated. To register, call registerContentObserver(). By default, CursorAdapter objects will get this notification.

参数

observer     The observer that originated the change, may be null .用以说明observer是第一个发现内容改变的ContentObserver,可为null.

通知所有注册到uri的监听器,告诉他们内容发生了改变。

public voidnotifyChange (Uri uri, ContentObserver observer, boolean syncToNetwork)

Notify registered observers that a row was updated. To register, call registerContentObserver(). By default, CursorAdapter objects will get this notification.

参数

observer     The observer that originated the change, may be null 用以说明observer是第一个发现内容改变的ContentObserver,可为null

syncToNetwork     If true, attempt to sync the change to the network.

注1:"基于uri的内容监测的基本模式被android.content.ContentResolver实现",严格来说ContentResolver至少提供了接口。

真正的实现在android.content.ContentService.

其实ContentResolver为基于Uri的内容监测所提供的方法只是调用ContentService相关的方法

注2:"注册监听器到uri"只是说如果notifyChange的uri和registerContentObserver中的uri相匹配,则调用observer的方法onChange。

内容监听器ContentObserver主要有三个方法

public boolean deliverSelfNotifications ()

Returns true if this observer is interested in notifications for changes made through the cursor the observer is registered with.

注:这个函数的使用还是puzzle.

public final void dispatchChange (boolean selfChange)

注:这个是为提供用handler执行onChange的一个接口。所以一般比没必要重载它。

public void onChange (boolean selfChange)

This method is called when a change occurs to the cursor that is being observed.

参数

selfChange     true if the update was caused by a call to commit on the cursor that is being observed.

注1:这个就是我们需要重载的函数,在里面可以实现对内容改变的个性化响应。

关于ContentObserver的更多内容请参阅《内容监听器ContentObserver》。

基本使用是这样的:

首先使用registerContentObserver注册observer监听器到uri,然后在内容发生改变时,就调用notifyChange通知系统所有注册到该uri的监听器,告诉他们内容发生了改变。

这时相应的监听器的dispatchChange方法被调用,在dispatchChange中onChange被调用。

最后如果不想让observer监听器uri相关的内容监听,可以调用unregisterContentObserver来取消注册。

对数据库改变的监测是如何实现的呢?

在providers对数据进行改变后,会通过getContext().getContentResolver().notifyChange的发生相应的uri的内容发生了改变

比如:com.android.providers.contacts中的ContactsProvider2

ContactsProvider2.java文件

public classContactsProvider2extendsSQLiteContentProvider implements OnAccountsUpdateListener {

-------------------省略------------------

@Override

public Uri insert(Uri uri, ContentValues values) {

waitForAccess();

return super.insert(uri, values);

}

@Override

public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {

-------------------省略------------------

waitForAccess();

return super.update(uri, values, selection, selectionArgs);

}

@Override

public int delete(Uri uri, String selection, String[] selectionArgs) {

waitForAccess();

return super.delete(uri, selection, selectionArgs);

}

}

-------------------省略------------------

protected voidnotifyChange(){

notifyChange(mSyncToNetwork);

mSyncToNetwork = false;

}

protected voidnotifyChange(boolean syncToNetwork) {

getContext().getContentResolver().notifyChange(ContactsContract.AUTHORITY_URI, null,

syncToNetwork);

}

-------------------省略------------------

}

SQLiteContentProvider.java文件

public abstract classSQLiteContentProviderextendsContentProvider

implements SQLiteTransactionListener {

@Override

public Uri insert(Uri uri, ContentValues values) {

Uri result = null;

boolean applyingBatch = applyingBatch();

if (!applyingBatch) {

mDb = mOpenHelper.getWritableDatabase();

mDb.beginTransactionWithListener(this);

try {

result = insertInTransaction(uri, values);

if (result != null) {

mNotifyChange = true;

}

mDb.setTransactionSuccessful();

} finally {

mDb.endTransaction();

}

onEndTransaction();

} else {

result = insertInTransaction(uri, values);

if (result != null) {

mNotifyChange = true;

}

}

return result;

}

public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {

-------------------省略------------------

}

public int delete(Uri uri, String selection, String[] selectionArgs) {

-------------------省略------------------

}

-------------------省略------------------

protected abstract voidnotifyChange();

-------------------省略------------------

protected voidonEndTransaction(){

if(mNotifyChange) {

mNotifyChange = false;

notifyChange();

}

}

-------------------省略------------------

}

那么Cursor是如何实现对基于uri的数据库内容变化进行监听呢?

只要把一个监听器ContentObserver对uri使用ContentResolver的registerContentObserver方法进行注册。

如果相应uri的数据库内容变化发变化,先通知ContentObserver,再又让它通知Cursor。

当然为了方便系统把ContentObserver设计成了内部类。

具体可见在Cursor接口的一个实现android.database.AbstractCursor。

AbstractCursor.java文件请见附件1

同时Cursor为我们提供了setNotificationUri(ContentResolver cr, Uri notifyUri)让它内部类的ContentObserver注册到ContentResolver的某个Uri上.

具体代码参见附件1。

那么外部如何监听Cursor呢?。

Cursor为外部监测数据库的变化提供了以下接口:

abstract void    registerContentObserver(ContentObserver observer)

Register an observer that is called when changes happen to the content backing this cursor.

注1:当数据库内容变化时通知observer,具体见附件1的onChange(boolean selfChange)函数.

注2:这个监听器observer主要是在setNotificationUri(ContentResolver cr, Uri notifyUri)中notifyUri对应的数据库内容发生变化时被通知的(间接),

abstract void     unregisterContentObserver(ContentObserver observer)

Unregister an observer that has previously been registered with this cursor via registerContentObserver(ContentObserver).

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值