原文:https://developer.android.google.cn/guide/topics/providers/content-provider-basics.html
Content Provider基础
Content Provider管理对中央数据仓库的访问,它是Android应用的一部分,通常会提供自己的UI来使用数据。然而,Content Provider主要是为了给其他应用使用而设计的,这些应用可以通过Provider客户端程序访问内容提供者。Provider和Provider客户端共同提供了一个稳定的、标准的访问数据的接口,并且也很好地解决了进程间通信和安全访问数据的问题。
一般来说,你会在这两种场合下使用Content Provider:想要访问其他程序中一个已有的Content Provider,或是想要在应用中创建一个新的Content Provider来和其他应用分享数据。
本文主要讲述了以下几点:
- Content Provider是如何工作的。
- 从Content Provider中获取数据的API。
- 插入、更新、删除Content Provider中的数据的API。
- 其他能够让你更加方便地使用Content Provider的API。
概述
Content Provider利用若干张表来向外部应用提供数据,这些表的形式类似于关系型数据库中的表。表中的每行代表Provider收集的某类数据的一个实例,每列代表数据的一个部分。
Content Provider通过众多的API和构建管理到应用的数据存储层的访问,包括:
- 与其他应用分享你的应用中的数据。
- 向控件发送数据。
- 利用搜索框架,通过SearchRecentSuggestionsProvider向你的应用返回定制的搜索建议。
- 通过实现AbstractThreadedSyncAdapter同步你的服务器和应用的数据。
- 通过CursorLoader为你的UI加载数据。
访问一个Content Provider
当你想要访问Content Provider中的数据时,你需要使用你的应用的Context中的ContentResolver对象,它可以作为一个客户端来与Provider进行交流。和ContentResolver对象进行交流的是ContentProvider的实现类的一个实例。这个Provider实例从客户端接收数据请求,执行被请求的行为,并最终返回结果。ContentResolver类提供了对永久存储的基础的增删改查的方法。
使用CursorLoader执行异步查询是从UI访问 ContentProvider对象的一个常用模式。UI中的Activity或者Fragment通过CursorLoader执行查询操作,并最终利用ContentResolver获得ContentProvider对象。这让你的UI在查询过程中也能和用户交互。这个模式涉及到一系列的对象,如下图所示:
注意:想要访问Provider,你的应用通常需要在manifest文件中声明相应的权限。
用户词典是Android平台的一个内嵌的Provider,它存储了用户想要保存的一些非常规的单词。
表1:
word | app id | frequency | locale | _ID |
---|---|---|---|---|
mapreduce | user1 | 100 | en_US | 1 |
precompiler | user14 | 200 | fr_FR | 2 |
applet | user2 | 225 | fr_CA | 3 |
const | user1 | 255 | pt_BR | 4 |
int | user5 | 100 | en_UK | 5 |
表1中,每行代表一个单词,这个单词可能不能在标准字典中找到。每列代表这个单词的某些方面的信息,比如首次遇到的地点。每列的头是它们在Content Provider中的列名。这个Provider中,_ID列充当了主键的角色,它是Provider自动保持的。
为了从用户词典中获取单词和它们的地点,你需要调用ContentResolver.query()。这个方法会调用用户词典Provider定义的ContentProvider.query()方法。下面是使用ContentResolver.query()的一个示例:
// 查询用户词典并返回结果
mCursor = getContentResolver().query(
UserDictionary.Words.CONTENT_URI, // 单词表的内容URI
mProjection, // 需要返回的列
mSelectionClause // 选取准则
mSelectionArgs, // 选取准则
mSortOrder);