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 void notifyChange (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 class ContactsProvider2 extends SQLiteContentProvider 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 void notifyChange() {
notifyChange(mSyncToNetwork);
mSyncToNetwork = false;
}
protected void notifyChange(boolean syncToNetwork) {
getContext().getContentResolver().notifyChange(ContactsContract.AUTHORITY_URI, null,
syncToNetwork);
}
-------------------省略------------------
}
SQLiteContentProvider.java文件
public abstract class SQLiteContentProvider extends ContentProvider
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 void notifyChange();
-------------------省略------------------
protected void onEndTransaction() {
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).
Register an observer that is called when changes happen to the contents of the this cursors data set, for example, when the data set is changed via requery(), deactivate(), or close().
注1:当Cursor发生requery(), deactivate(), or close()时通知DataSetObserver observer
Unregister an observer that has previously been registered with this cursor via registerContentObserver(ContentObserver).
void | onChanged() |
void |
onInvalidated()
This method is called when the entire data becomes invalid, most likely through a call to
deactivate() or close() on a Cursor . |
它当然是借助Cursor来实现的。
但是CursorAdapter与ContentObserver相对应对外提供(可以重载)的接口是:
onContentChanged()
当时CursorAdapter与DataSetObserver相对应对外提供(可以重载)的接口是:
onChanged()->notifyDataSetChanged()//这个消息并完全不是从Cursor传递来,它会在CursorAdapter内手动被调用
onInvalidated()->notifyDataSetInvalidated()//这个消息并不是从Cursor传递来。
具体可以参照附件2的android.widget.CursorAdapter源代码
CursorAdapter的notifyDataSetChanged()和notifyDataSetInvalidated()事件可以继续往外传递
void |
notifyDataSetChanged()
Notifies the attached observers that the underlying data has been changed and any View reflecting the data set should refresh itself.
|
void |
notifyDataSetInvalidated()
Notifies the attached observers that the underlying data is no longer valid or available.
|
void |
registerDataSetObserver(DataSetObserver observer)
Register an observer that is called when changes happen to the data used by this adapter.
|
void |
unregisterDataSetObserver(DataSetObserver observer)
Unregister an observer that has previously been registered with this adapter via
registerDataSetObserver(DataSetObserver) . |
转:
http://hubingforever.blog.163.com/blog/static/1710405792010101541326636/
发表评论
-
资料上传备份
2012-07-02 07:28 0对付对付对付对付 -
Android-sharedUserId数据权限
2012-05-02 10:16 1444Android-sharedUserId数据权限 An ... -
Android Service学习之本地服务
2012-04-18 10:28 862转: Android Service学习之本地服务 htt ... -
match_parent和fill_parent的区别 .
2012-02-18 11:49 1839match_parent和fill_parent的区别 有 ... -
Android中SQLiteOpenHelper类的onUpgrade方法的作用
2012-02-09 11:50 4600Android中SQLiteOpenHelper类的onUpg ... -
Android启动各种系统服务线程
2012-02-09 10:59 1935Android启动各种系统服务 ... -
android
2012-02-08 09:22 0Android数据库内容变化的监听 首先介绍内容监 ... -
在线升级Android应用程序的思路
2012-02-07 11:34 876在线升级Android应用程序的思路 http://www. ... -
android中的数据库操作
2012-02-07 10:50 1450android中的数据库操作 ... -
SQLiteOpenHelper类与自动升级数据库
2012-02-07 10:31 2281SQLiteOpenHelper类与自动升级数据库 S ... -
SQLite外键的实现
2012-02-07 10:30 1715SQLite外键的实现 SQLite现在的版本还不支持 ... -
29日修改数据库设计
2012-01-29 15:24 0数据表设计: 账号信息表account ... -
最新数据库设计
2012-01-28 21:21 0数据表设计: 工资管理 账号信息表Acc ... -
数据库设计
2012-01-11 15:27 0数据库设计 信息表:infotypecreate ta ... -
Android到处都在使用的回调分析
2011-12-21 15:53 3545Android到处都在使用的回调分析 ... -
android中LayoutInflater的使用
2011-12-21 11:35 1932android中LayoutInflater的使用 ... -
cmd下操作mysql
2011-12-20 14:11 985cmd下操作mysql 连接mysql服务器 mysql ... -
SIM卡满处理流程分析
2011-12-19 15:15 1881SIM卡满处理流程分析 //框架层分析 // SMSD ... -
短信发送状态报告流程分析
2011-12-19 15:07 2392短信发送状态报告流程分析 //应用层分析: //Sms ... -
Android平台 短信接送流程剖析(含编码)
2011-12-16 15:29 3227Android平台 短信接送流程剖析(含编码) ...
相关推荐
在Android开发中,监听短信数据库的变化是一项常见的需求,尤其是在实现如短信自动回复、短信通知等功能时。通过监听短信数据库,开发者可以实时获取到用户手机上接收到的新短信或已有的短信变化,从而进行相应的...
在应用不再需要监听数据库变化时,记得注销`ContentObserver`,防止内存泄漏: ```java contentResolver.unregisterContentObserver(myContentObserver); ``` `MyContentObserver`是文件列表中提供的示例类,可能...
此外,ObjectBox还支持监听数据变化,例如,可以通过`Observer`接口实现对数据的实时监听,当数据发生变化时,会触发回调函数。 总的来说,ObjectBox为Android开发者提供了一个高效、便捷的数据存储解决方案,使得...
4. 创建`ContentObserver`监听数据库变化,并通过`Handler`更新UI。 5. 在活动的生命周期方法中注册和注销`ContentObserver`。 这样的实现方式使得应用能够记录和展示接收到的广播信息,提供了一种跟踪系统广播行为...
这个"Android数据库Demo-GreenDaoTest.zip"是一个演示如何使用GreenDao的实例,通过分析这个Demo,我们可以深入理解GreenDao的用法和优势。 首先,GreenDao的核心思想是将Java对象映射到SQLite数据库中的表格,这样...
- **监听**:在Android中,监听通常涉及注册广播接收器、服务或者ContentObserver,用于监听特定事件的发生,如系统广播、数据库变化等。 - **打开app**:在Android中,应用的启动和关闭都是通过Activity的生命周期...
3. **监听短信数据库变化的示例** - 在提供的代码示例中,`SMSContentObserver`是一个自定义的ContentObserver,用于监听短信数据库的变化。它在构造函数中接收一个Handler,这通常用于在主线程中更新UI。 - 当`...
综上所述,实现“实时监听并读取微信最新消息”的功能是一项技术性较强的任务,涉及到Android系统的底层操作、文件监控、数据库解析等多个环节,需要开发者具备扎实的Android编程基础和良好的问题解决能力。...
总结,"sms.zip_Android 数据库_android_android sms_sms"涵盖了Android平台下使用SQLite数据库管理和操作短信数据的相关技术,包括数据库操作、广播接收器、内容提供者、权限控制以及数据备份恢复等多个方面。...
接下来,我们关注“Android数据库”。在Android上,SQLite是最常用的关系型数据库管理系统,它轻量级且高效,适用于存储应用数据。开发者可以创建表,插入、更新和删除数据,并执行查询来获取所需的信息。当涉及到...
相比之下,ContentObserver是一种更高效且推荐的方法,它通常用于监听数据库或共享首选项的变化。虽然ContentObserver不直接支持文件系统,但我们可以借助IntentService和BroadcastReceiver来扩展其功能。创建一个...
在Android开发中,...通过以上步骤,你就可以成功地在Android的ListView中显示数据库中的内容了。这不仅可以提高用户体验,还能方便地管理和操作数据。记住,理解并熟练运用这些知识点是Android开发中的基础技能。
在Android开发中,数据库的选择和使用是至关重要的。Realm是一个高效、现代且易于使用的对象关系映射(ORM)数据库,特别适合移动平台。本篇将深入探讨如何对Android中的Realm数据库进行逻辑封装,以实现更高效、可...
使用`TelephonyManager`类可以监听电话状态的变化。注册一个`PhoneStateListener`,并重写`onCallStateChanged()`方法,可以在电话状态改变时接收到回调,例如来电、去电、通话结束等。 3. **短信监听**: 监听...
LitePal是一款轻量级的Android数据库框架,由国内知名Android开发者郭霖开发并维护。它基于流行的ORM(Object-Relational Mapping)技术,使得开发者能够更便捷地在Android应用中进行数据库操作,大大简化了传统...
1. 创建一个BroadcastReceiver,监听特定事件(例如数据库变化)。 2. 当事件触发时,计算未读消息的数量。 3. 使用NotificationManager创建一个Notification,设置角标显示未读数量。 4. 如果支持,使用...
- **监听数据变化**:可以注册监听器,当数据库中的数据发生变化时,自动触发回调。 - **批量操作**: LitePal提供了批量插入和更新的功能,提高了性能。 - **异步操作**:对于耗时的操作,如大量数据的读写, ...
在Android平台上进行应用程序开发时,通信录管理是一个常见的需求,而使用数据库来实现通信录功能是一种高效且灵活的方法。...对于想要学习Android数据库应用开发的人员来说,这是一个很好的实践案例。
总之,实现Android应用中的白天夜晚模式切换,主要涉及BroadcastReceiver监听系统时间变化、AppCompatDelegate切换主题模式以及设置界面的用户交互。通过以上步骤,你就可以为自己的应用添加这一实用功能了。