在Android开发中,监听数据库变化并及时更新界面是常见的需求。为了实现这一功能,可以使用以下步骤:
-
监听数据库变化:首先,你需要在应用程序中注册一个内容观察者(Content Observer)来监听数据库的变化。内容观察者将监视指定的数据源(如数据库)并接收有关数据更改的通知。在内容发生改变时,就调用
notifyChange
通知系统所有注册到该uri的监听器,告诉他们内容发生了改变。)= -
实现内容观察者:创建一个继承自
ContentObserver
的类,并重写其onChange()
方法。在onChange()
方法中,你可以执行与UI相关的操作,比如更新界面或执行其他逻辑。 -
注册内容观察者:在你的Activity或Fragment中,通过调用
getContentResolver().registerContentObserver()
方法,将你实现的内容观察者对象注册到相应的数据源上。 -
更新界面:当数据库中的数据发生变化时,内容观察者的
onChange()
方法将被触发。在该方法中,你可以获取最新的数据并更新UI,例如通过调用适配器的notifyDataSetChanged()
方法来刷新列表视图。
监听数据库变化并及时更新界面的意义在于提供了实时展示最新数据的能力,从而增强了用户体验和数据的一致性。它可以保持应用程序与数据库之间的同步,并使用户能够看到最新的数据状态。这在需要显示动态数据、实时聊天、数据同步等场景下非常有用。
然而,需要注意以下几点:
-
在注册内容观察者时,你应该选择正确的URI来监视数据库的特定表或数据集。使用错误的URI可能导致监听失败或不必要的更新。
-
内容观察者的
onChange()
方法是在后台线程中调用的,如果你需要在其中更新UI,确保在主线程中执行UI操作。 -
当监听到数据库变化时,要谨慎处理数据更新操作,尽量避免耗时操作或频繁的UI更新,以便维持应用程序的性能和流畅度。
总之,通过监听数据库变化并及时更新界面,你可以实现实时展示最新数据的功能,提升用户体验和数据同步性。
关于ContentResolver
首先介绍内容监测的基本模式, 基于uri的内容监测的基本模式被android.content.ContentResolver实现。
ContentResolver为此提供了三个方法:
-
注册监听器到某个uri
public final void registerContentObserver (Uri uri, boolean notifyForDescendents, ContentObserver observer) -
取消被注册的监听器
public final void unregisterContentObserver (ContentObserver observer) -
通知所有注册到uri的监听器,告诉他们内容发生了改变。
public void notifyChange (Uri uri, ContentObserver observer) -
通知所有注册到uri的监听器,告诉他们内容发生了改变。
public void notifyChange (Uri uri, ContentObserver observer, boolean syncToNetwork)
注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.
注:这个就是我们需要重载的函数,在里面可以实现对内容改变的个性化响应。
ContentObserver 监听数据库变化
要在Android中监听数据库的变化并更新界面,你可以使用ContentObserver来实现。ContentObserver是一个用于监听ContentProvider的变化的类,可以用于监视数据库的变化并在数据更新时通知你。
下面是一些基本的步骤来实现这个功能:
- 创建一个自定义的ContentObserver类,重写其onChange()方法。在onChange()方法中,你可以执行更新界面的操作。
public class MyContentObserver extends ContentObserver {
public MyContentObserver(Handler handler) {
super(handler);
}
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
// 数据库发生变化,执行更新界面的操作
updateUI();
}
private void updateUI() {
// 在这里更新你的界面
}
}
- 在你的Activity或Fragment中,注册ContentObserver来监听数据库的变化。
// 创建ContentObserver对象
MyContentObserver contentObserver = new MyContentObserver(new Handler());
// 注册ContentObserver
getContentResolver().registerContentObserver(uri, true, contentObserver);
在上述代码中,uri
是要监听的数据库内容的URI。可以根据你的具体情况,将其替换为你要监听的数据库的URI。
- 在Activity或Fragment的生命周期方法中,注册和取消注册ContentObserver。
@Override
protected void onResume() {
super.onResume();
// 注册ContentObserver
getContentResolver().registerContentObserver(uri, true, contentObserver);
}
@Override
protected void onPause() {
super.onPause();
// 取消注册ContentObserver
getContentResolver().unregisterContentObserver(contentObserver);
}
在上述代码中,uri
是要监听的数据库内容的URI,contentObserver
是之前创建的ContentObserver对象。
通过以上步骤,你可以在Android中监听数据库的变化并在数据更新时更新界面。当数据库内容发生变化时,ContentObserver会调用onChange()方法,在该方法中你可以执行更新界面的操作。
请注意,这只是一个基本的示例,你需要根据你的具体需求来实现ContentObserver和更新界面的逻辑。
数据库 URI 的构造
在Android中,URI(Uniform Resource Identifier)用于标识和定位资源。对于数据库操作,你可以使用ContentProvider提供的URI来进行访问。
构造URI时,你可以使用Uri.Builder类来构建URI对象。下面是一些示例,展示了如何构造URI:
- 构造基本的URI:
Uri uri = Uri.parse("content://com.example.provider/table_name");
在上述示例中,com.example.provider
是ContentProvider的授权名称,table_name
是要操作的表名。
- 构造带有参数的URI:
Uri uri = Uri.parse("content://com.example.provider/table_name/1");
在上述示例中,1
是一个参数值,用于指定要操作的行(row)的ID。
- 使用Uri.Builder构建URI:
Uri.Builder builder = new Uri.Builder();
builder.scheme("content")
.authority("com.example.provider")
.appendPath("table_name")
.appendPath("1");
Uri uri = builder.build();
在上述示例中,我们使用Uri.Builder类来构建URI对象。通过指定scheme、authority、path等部分,逐步构建URI对象。build()
方法最终返回构建的URI对象。
请根据你的具体情况和需求来构建URI。URI的结构取决于你使用的ContentProvider的实现和数据结构。
注意:上述示例中的URI仅供参考,实际情况下需要根据你的项目和ContentProvider的设计来构建适当的URI。
常见的数据库URI
在Android系统中,常见的数据库URI用于访问一些核心应用程序的数据,例如媒体库、通讯录等。下面列举了一些常见的系统数据库URI:
-
媒体库(Media Store):
- 外部图片:
MediaStore.Images.Media.EXTERNAL_CONTENT_URI
- 外部视频:
MediaStore.Video.Media.EXTERNAL_CONTENT_URI
- 外部音频:
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
- 内部图片:
MediaStore.Images.Media.INTERNAL_CONTENT_URI
- 内部视频:
MediaStore.Video.Media.INTERNAL_CONTENT_URI
- 内部音频:
MediaStore.Audio.Media.INTERNAL_CONTENT_URI
- 外部图片:
-
通讯录(Contacts):
- 联系人:
ContactsContract.Contacts.CONTENT_URI
- 联系人数据:
ContactsContract.Data.CONTENT_URI
- 联系人电话号码:
ContactsContract.CommonDataKinds.Phone.CONTENT_URI
- 联系人邮箱:
ContactsContract.CommonDataKinds.Email.CONTENT_URI
- 联系人地址:
ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_URI
- 联系人:
-
短信(SMS):
- 所有短信:
Telephony.Sms.CONTENT_URI
- 收件箱:
Telephony.Sms.Inbox.CONTENT_URI
- 发件箱:
Telephony.Sms.Sent.CONTENT_URI
- 草稿箱:
Telephony.Sms.Draft.CONTENT_URI
- 所有短信:
-
通话记录(Call Log):
- 所有通话记录:
CallLog.Calls.CONTENT_URI
- 已拨通话记录:
CallLog.Calls.OUTGOING_TYPE
- 已接通话记录:
CallLog.Calls.INCOMING_TYPE
- 未接通话记录:
CallLog.Calls.MISSED_TYPE
- 所有通话记录:
这些URI提供了访问系统数据库中特定数据的方式。你可以使用ContentResolver来查询、插入、更新和删除与这些URI对应的数据,以便读取或修改这些核心应用程序的数据。需要注意的是,不同的Android版本可能会有一些差异,在使用这些URI时请参考具体的API文档以确保正确访问数据库。
相关参考
https://blog.csdn.net/hudashi/article/details/7013362