Android 实现数据库变化的监听 (android 监听数据库变化)

在开发 Android 应用程序时,我们经常会使用数据库来存储应用的数据。而随着应用程序的运行,数据也会不断地改变。如果我们能够实现对数据库变化的实时监听,就可以在数据变化时做出相应的操作,提高应用程序的运行效率和用户体验。

Android 提供了 SQLite 数据库作为默认的数据库引擎,并且支持 ContentProvider 来对数据库进行封装和管理。在这种情况下,Android 提供了两种方式来实现对数据库变化的监听:ContentObserver 和 BroadcastReceiver。

一、ContentObserver

ContentObserver 是一个用于观察 ContentProvider 的变化的观察者。我们可以使用它来监听数据库的变化,并做出相应的操作。

使用 ContentObserver 需要继承它,并重写onChange() 方法。在这个方法里面,我们可以获取到发生变化的 Uri,并根据 Uri 来做出不同的操作。下面是一个简单的例子:

“`

public class MyContentObserver extends ContentObserver {

private Context mContext;

public MyContentObserver(Context context) {

super(null);

mContext = context;

}

@Override

public void onChange(boolean selfChange) {

super.onChange(selfChange);

// 处理数据库变化的逻辑

}

@Override

public void onChange(boolean selfChange, Uri uri) {

super.onChange(selfChange, uri);

if (uri.equals(MyContentProvider.URI_STUDENTS)) {

// 处理学生表的变化

} else if (uri.equals(MyContentProvider.URI_TEACHERS)) {

// 处理教师表的变化

} else {

// 其他表的变化

}

}

}

“`

在这个例子中,我们继承了 ContentObserver,并在 onChange() 方法里面获取到了数据库变化的 Uri。然后根据 Uri 来做出相应的操作。需要注意的是,我们可以在构造方法中传入 null,因为这个参数在这个例子中并没有用到。

在使用 ContentObserver 时,我们还需要使用 ContentResolver 注册 ContentObserver 对象,并绑定监听的 Uri。

“`

MyContentObserver observer = new MyContentObserver(mContext);

mContext.getContentResolver().registerContentObserver(MyContentProvider.URI_STUDENTS, true, observer);

“`

在这个例子中,我们注册了一个 ContentObserver 对象,用来监听学生表的变化。

二、BroadcastReceiver

除了使用 ContentObserver,我们还可以使用 BroadcastReceiver 来监听数据库的变化。BroadcastReceiver 是 Android 提供的一种可以接收广播消息的组件。我们可以通过广播消息来实现数据的通知和同步等功能。

在 Android 中,有两种方式可以实现数据库的广播通知:Intent.ACTION_PROVIDER_CHANGED 和自定义广播消息。

1. 使用 Intent.ACTION_PROVIDER_CHANGED

Intent.ACTION_PROVIDER_CHANGED 是一个系统定义的广播消息,用于通知 ContentProvider 的变化。我们可以在 BroadcastReceiver 中通过 IntentFilter 来匹配这个广播消息,并在 onReceive() 方法中对广播消息进行处理。

下面是一个简单的例子:

“`

public class MyBroadcastReceiver extends BroadcastReceiver {

@Override

public void onReceive(Context context, Intent intent) {

String action = intent.getAction();

if (Intent.ACTION_PROVIDER_CHANGED.equals(action)) {

Uri uri = intent.getData();

if (uri.equals(MyContentProvider.URI_STUDENTS)) {

// 处理学生表的变化

} else if (uri.equals(MyContentProvider.URI_TEACHERS)) {

// 处理教师表的变化

} else {

// 其他表的变化

}

}

}

}

“`

在这个例子中,我们继承了 BroadcastReceiver,并在 onReceive() 方法中,根据收到的广播消息来做出相应的操作。需要注意的是,我们在广播消息中传递的是一个 Uri 对象,而不是 ContentObserver 中的 UriMatcher。

在使用 BroadcastReceiver 时,我们需要在 AndroidManifest.xml 中注册这个组件,并设置相应的 IntentFilter。

“`

“`

在这个例子中,我们注册了一个 BroadcastReceiver,用来监听我们自定义的 ContentProvider 的变化。需要注意的是,我们需要设置相应的 scheme 和 host,以匹配我们的 ContentProvider。

2. 自定义广播消息

除了使用系统定义的广播消息,我们还可以自定义广播消息来实现数据库变化的监听。我们可以在 ContentProvider 中发送自定义广播消息,并在 BroadcastReceiver 中通过注册相应的 IntentFilter 来监听这些消息。

下面是一个简单的例子:

“`

public class MyContentProvider extends ContentProvider {

public static final String ACTION_STUDENTS_CHANGED = “com.example.mycontentprovider.students_changed”;

public static final String ACTION_TEACHERS_CHANGED = “com.example.mycontentprovider.teachers_changed”;

public static final Uri URI_STUDENTS = Uri.parse(“content://com.example.mycontentprovider/students”);

public static final Uri URI_TEACHERS = Uri.parse(“content://com.example.mycontentprovider/teachers”);

@Override

public boolean onCreate() {

// 初始化数据库

return true;

}

@Nullable

@Override

public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {

// 查询数据

return null;

}

@Nullable

@Override

public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {

// 插入数据

notifyChanged(uri);

return null;

}

@Override

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

// 更新数据

notifyChanged(uri);

return 0;

}

@Override

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

// 删除数据

notifyChanged(uri);

return 0;

}

@Nullable

@Override

public String getType(@NonNull Uri uri) {

return null;

}

private void notifyChanged(Uri uri) {

String action = null;

if (uri.equals(URI_STUDENTS)) {

action = ACTION_STUDENTS_CHANGED;

} else if (uri.equals(URI_TEACHERS)) {

action = ACTION_TEACHERS_CHANGED;

}

if (action != null) {

getContext().sendBroadcast(new Intent(action));

}

}

}

“`

在这个例子中,我们在 insert()、update() 和 delete() 方法里面,发送了自定义的广播消息。这些消息分别对应了学生表和教师表的变化。在发送广播消息时,我们使用了 Android 的 Context 类来获取到一个广播的发送器,并通过 Intent 来传递广播消息。

在上面的代码中,我们使用了一个名为 notifyChanged() 的方法来发送广播消息。这个方法的作用是根据传入的 Uri 判断要发送哪种类型的广播消息。在这个方法里面,我们创建了一个新的 Intent,并调用了 sendBroadcast() 方法来发送广播消息。这个方法会将广播消息发送到所有已经注册了相应 IntentFilter 的 BroadcastReceiver。

在使用自定义广播消息时,我们还需要在 BroadcastReceiver 中注册 IntentFilter,并监听相应的广播消息。

“`

public class MyBroadcastReceiver extends BroadcastReceiver {

@Override

public void onReceive(Context context, Intent intent) {

String action = intent.getAction();

if (MyContentProvider.ACTION_STUDENTS_CHANGED.equals(action)) {

// 处理学生表的变化

} else if (MyContentProvider.ACTION_TEACHERS_CHANGED.equals(action)) {

// 处理教师表的变化

} else {

// 其他消息的处理

}

}

}

“`

在这个例子中,我们注册了一个 BroadcastReceiver,并设置相应的 IntentFilter,以监听我们发送的广播消息。

“`

“`

需要注意的是,我们在 IntentFilter 中设置的是可以匹配上我们发送的广播消息的唯一标识符,而不是发送的 Uri。

ContentObserver 和 BroadcastReceiver 都是 Android 提供的用于监听数据库变化的方式。我们可以根据自己的需求选择适合自己的方式。在使用 ContentObserver 时,我们需要使用 ContentResolver 注册 ContentObserver 对象,并绑定监听的 Uri。在使用 BroadcastReceiver 时,我们需要在 AndroidManifest.xml 中注册 BroadcastReceiver,并设置相应的 IntentFilter。无论我们选择哪种方式,都可以实现对数据库变化的监听,并做出相应的操作。

相关问题拓展阅读:

android 怎么解决反复监听ContentObserver的问题

我也遇到了

最新来的短信,应该是未读的,你可以在onChange()里,判断之一条是不扒数是有未读标志,是的话,悔此宏再删除呀碧册!

直接判断短信日期就行了 只删除最新的一条

期待大牛答案{in:}

高手们快来回答。。。。

android源码中有launcher2launcher3,用的是哪个

1、Launcher进程启动过程

可以由下面图看到Launcher进程是如何被创建启动:

Activity Manager通过发送Intend来启动Launcher。

Intent intent = new Intent(mTopAction, mTopData != null ?

Uri.parse(mTopData) : null);

intent.setComponent(mTopComponent);

if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL)

{

intent.addCategory(Intent.CATEGORY_HOME);

}

startActivityLocked(null, intent, null, null, 0, aInfo,

null, null, 0, 0, 0, false, false);

复制代码

因此,如果你要开机启动一个替换Launcher的程序,只要在程序里面加入action.MAIN 、

category.HOME、category.DEFAULT就可以。如果出现多个程序穗野老都加入这种intent,系统会弹出让你选择

哪个作为启动器。

2、Launcher初始化——LauncherApplication。

Application类,我想大部分做Android应用的朋友都用过,每个Android应用默认都有一个Application类,

你也可以继承Application类,然后加入自己代码。Application是一个全局的应用类,在AndroidManifest.xml

我们也可以找到Application标签。

复制代码

Android四大组件的声明都需要放到application标签里面,默认使用的是系统的Application类,如果你在项目里面重载了脊轮它。就需要在标签,name属性下写上你的新的Application类名。Launcher里面就是继承了Application为LauncherApplication。应用启动的时候首先会加载Application。我们可以看到Launcher主类Launcher.java的onCreate函数里面,之一个就是获取Application的实例。

LauncherApplication app = ((LauncherApplication)getApplication());

复制代码

接下来我们看看LauncherApplication里面初始化,LauncherApplication大部分工作就是在初始化完成,剩下都是一些返回接口。

@Override

public void onCreate()

{

super.onCreate();

//获取屏幕大小,主要用来区分手机还是平板

final int screenSize = getResources().getConfiguration().screenLayout &

Configuration.SCREENLAYOUT_SIZE_MASK;

sIsScreenLarge = screenSize == Configuration.SCREENLAYOUT_SIZE_LARGE ||

screenSize == Configuration.SCREENLAYOUT_SIZE_XLARGE;

//屏幕密度

sScreenDensity = getResources().getDisplayMetrics().density;

     //IconCahe里面保存了界面所有应用图标的绘画需要的数据,这个到时候具体分析再说。

//加入这东西的主要原因是为了提高绘画界面的效率

mIconCache = new IconCache(this);

//数据库加载类,LauncherModel是Launcher里面非常重要的一个类,相当于MVC模式里面的

     //Model功能,管理数据和初始化数据

mModel = new LauncherModel(this, mIconCache);

//下面注册了一些监听器,主要包含APK文件更新删除等数据变化的时候接收的通知

  //接收通知后,主要是用来更新Launcher里面的数据库。因为桌面应用图标数据,只会加载一次

IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);

filter.addAction(Intent.ACTION_PACKAGE_REMOVED);

filter.addAction(Intent.ACTION_PACKAGE_CHANGED);

filter.addDataScheme(“package”);

registerReceiver(mModel, filter);

filter = new IntentFilter();

filter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);

filter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);

filter.addAction(Intent.ACTION_LOCALE_CHANGED);

filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);

registerReceiver(mModel, filter);

filter = new IntentFilter();

filter.addAction(SearchManager.INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED);

registerReceiver(mModel, filter);

filter = new IntentFilter();

filter.addAction(SearchManager.INTENT_ACTION_SEARCHABLES_CHANGED);

registerReceiver(mModel, filter);

     //contentresolver则是用于管理所有程序的contentprovider实例

ContentResolver resolver = getContentResolver();

//注册内容观察者,监听application数据库变化,回调

resolver.registerContentObserver(LauncherSettings.Favorites.CONTENT_URI, true, mFavoritesObserver);

}

复制代码

上面是LauncherApplication最主要的工作,初始化整个Launcher的一些关键类,和注册一些监听器。主要都是用来监听应用的安装更新删除等导致Launcher数据库变化的操作。Launcher数据都是使用contentprovider来提供数据。其中注册的监听接口是

private final ContentObserver mFavoritesObserver = new ContentObserver(new Handler())

{

@Override

public void onChange(boolean selfChange)

{

//重新加载界面数据

mModel.startLoader(LauncherApplication.this, false);

}

};

复制代码

LauncherSettings.Favorites.CONTENT_URI里面数据发生变化的时候,都会调用mModel.startLoader()接口,

重新加载Launcher的数据。startLoader的具体操作,我后面分析LauncherModel类的时候会分析。这一块涉及

Launcher所有数据加载。剩下的接都是返回初始化时候创建的对象或者获取屏幕密度、获取是否大屏幕。

后面很多处理都需要判断是否是大屏幕,4.0以后手机平板都共用一套系统,导致多了很多处理。 3、Launcher.java初始化Launcher.java是Launcher里面最主要的类,是一个Activity。启动的之一个组件。既然是Activity,我们要分析它初始化,毫无疑问,需要找到onCreate()里面分析。把主要一些分析用注释方式写在代码里面,这样比较方便阅读。

关于android 监听数据库变化的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。


数据运维技术 » Android 实现数据库变化的监听 (android 监听数据库变化)