从较高的视角充分理解Android中MVC和内容提供者如何一起协同工作是非常重要的。此外,在Android中关于MVC的更详细的探讨将在P345“Network MVC”一节中进行。
为了理解内容提供者框架的功能,需要先弄清楚游标更新事件是如何驱动Android UI动态更新的。这里有必要对在传统的MVC编程模式中经常被忽略的通信模式进行重点强调,这个过程中具体执行了如下动作:视图把用户输入事件传递给控制器;控制器修改模型;模型把更新事件发送给视图及在模型中注册了的所有观察器;视图渲染模型中的内容,通常不需要应用逻辑的直接参与,理想情况下只需要对模型中的数据进行迭代。
在Android中,MVC模式的工作原理如图12-3所示,其中:
·模型部分包括内容提供者和query方法所返回的光标,以及SQLite数据库表中所存储的数据。
·在实现上,当内容提供者调用ContentResolver.notifyChange方法修改数据时,应该发送事件通知。因为提供者修改数据只有一种方式,只要数据发生变化,它都能知道。
·事件通知发送给UI组件,通常是ListView,通过观察绑定在内容提供者URI的Cursor对象来进行。在响应提供者的notifyChange方法被调用时,cursor把模型中的消息更新给视图。视图和Android活动及其视图相对应,与控制器对应的则是监听它们生成的事件的类。具体而言,系统会发送ContentObserver.onChange消息给使用Cursor.registerContentObserver注册过的ContentObserver实例。当开发人员调用ListView.setAdapter(ListAdapter)方法时,Android类会自动注册游标变化。列表视图中包含了内部的内容观察器,列表适配器会注册Cursor对象。
假定有个活动要调用ContentResolver.delete方法,我们一起来看看这个通知机制实际上是如何工作的。首先,相应的内容提供者会从数据库中删除一条记录,然后通知该记录对应的解析程序URI。在视图中嵌入的所有监听游标会接到数据变化通知;视图会顺序接收到更新事件,并重新绘制以反映新的状态。视图会绘制其显示区域的任何状态;如果它包含要删除的元素,该元素会从UI中消失。Cursor对象是作为光标使用方和内容提供者系统之间的代理对象,事件从提供者通过光标流向视图系统。该事件序列的自动化可以给开发人员带来很大的便利,他们只需要编写很少的代码就可以运行。此外,程序不需要显式轮询就可以保持模型在渲染时是最新的,因为当状态改变时,模型会通知视图。
图12-3:在Android MVC中典型的光标和内容提供者的使用方式