在之前的开发中,我们在 TouristSpotContentProvider
函数 insert()
、delete()
、update()
中调用了代码:
// java
getContext().getContentResolver().notifyChange(uri, null);
// kotlin
context!!.contentResolver.notifyChange(uri, null)
这是在共享数据发生改变的情况下,对外发出通知——该 Uri
对应的数据发生了变化;
业务中,我们可以通过注册监听该 Uri
,从而在共享数据发生改变的时候作出响应。
想要实现观察监听共享数据发生改变的功能,那就要实行如下步骤:
- 创建一个“观察者”类,继承自
ContentObserver
,实现处理共享数据发生改变时的业务逻辑; - 创建该“观察者”类的实例,并注册该“观察者”到对应共享数据
Uri
。
代码实践
我们要“观察监听”之前开发的“旅游景点”共享数据的改变,是在项目 ContentProviderSample
代码基础上进行开发的。
1. 创建一个“观察者”类
在 MainActivity
中创建了一个“观察者”,它是一个内部类,继承了 ContentObserver
;
Java 代码
private final class TouristSpotObserver extends ContentObserver {
private static final String TAG = "TouristSpotObserver";
public TouristSpotObserver(Handler handler) {
super(handler);
}
@Override
public void onChange(boolean selfChange) {// 当数据变化,回调该函数
super.onChange(selfChange);
Log.i(TAG, "data changed");
}
}
Kotlin 代码
private class TouristSpotObserver(handler: Handler?) :
ContentObserver(handler) {
override fun onChange(selfChange: Boolean) { // 当数据变化,回调该函数
super.onChange(selfChange)
Log.i(TAG, "data changed")
}
companion object {
private const val TAG = "TouristSpotObserver"
}
}
我们在函数 onChange()
中编写共享数据发生改变时的业务逻辑,这里简化处理打印日志。
2. 注册数据监听
在 MainActivity
的函数 onCreate()
中注册数据监听,
Java 代码
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
......
registerContentObserver();
}
/**
* 注册数据监听器
*/
private void registerContentObserver() {
TouristSpotObserver observer = new TouristSpotObserver(new Handler());
getContentResolver().registerContentObserver(TouristSpot.Spot.TOURISTS_CONTENT_URI, true, observer);
getContentResolver().registerContentObserver(TouristSpot.Spot.SPOT_CONTENT_URI, true, observer);
}
Kotlin 代码
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
......
registerContentObserver()
}
/**
* 注册数据监听器
*/
private fun registerContentObserver() {
val observer = TouristSpotObserver(Handler())
contentResolver.registerContentObserver(
TouristSpot.Spot.TOURISTS_CONTENT_URI,
true,
observer
)
contentResolver.registerContentObserver(TouristSpot.Spot.SPOT_CONTENT_URI, true, observer)
}
首先创建“观察者”类的实例,然后调用了 getContentResolver().registerContentObserver()
分别针对 Uri
TouristSpot.Spot.TOURISTS_CONTENT_URI
和 TouristSpot.Spot.SPOT_CONTENT_URI
注册了数据监听。
3. 运行项目
运行项目,进入到 TouristSpotActivity
页面,输入“景点”信息,点击按钮插入数据;
界面刷新,数据插入成功了;然后查看日志台 Logcat
:
显示出了我们在函数 onChange()
中写的日志——共享数据变化被监听到了。
项目代码地址
Java 版:
https://github.com/BethelDEV/shaguaAndroid/tree/main/javaSource/ContentProviderSampleKotlin 版:
https://github.com/BethelDEV/shaguaAndroid/tree/main/kotlinSource/ContentProviderSample