Android四大控件之ContentProvider
16lz
2021-01-25
Hi,众猿们,今天咱们讲讲ContentProvider(内容提供者)对象。在Android系统中,ContentProvider为我们提供了一种跨应用共享数据的机制,即通过该对象,我们可以本应用的数据对外暴露,以供其它应用访问。开始介绍本之前对象我们需要介绍如何表示一个资源的信息(如它在什么位置,该怎么用等),这一知识涉及到两个对象:Uri和URL Uri:Uniform Resource Identifier,即统一资源标识符,用来唯一的标识一个资源,有时并未明确地表示出了资源的位置,有时由三部分组成: 1.访问资源的命名机制 :表明访问该资源需要使用什么协议,如http协议 2.存放资源的主机名 (authority):表明该资源所在的大致位置,如其所在的主机ip地址,当该资源是数据库的某个表中的一条数据时,这一部分还可以是该数据库所在的应用的唯一标示 3.资源自身的路径(path) :这部分对资源的位置进一步进行说明,如文件资源的文件名,数据库中的一条数据的主键值等 URL:Uniform Resource Location,即统一资源定位符,它是一种具体的Uri,不仅唯一标识资源,而且还明确地表示出了资源的位置,也由上面的三部分组成。数据也是一种资源,Android系统跨应用访问数据时是通过Uri来标示数据的,当我们希望访问其它程序的数据时,首先要确定该数据的Uri。 如:一个安卓程序中有一个包:lmz.contentprovider.provider,其作用是提供数据供其他应用,其SQLite数据库中有一张表,名为table,我们想在其它程序中访问该表中主键值为1的一条数据,则我们可以确定该条数据的Uri的各部分值为: 访问资源的命名机制:content(安卓中跨应用访问数据采用的是content协议) 存放资源的主机名 :在这个例子中为该应用程序的唯一标示,一般我们就采用应用程序中起共享数据作用的包名 :lmz.contentprovider.provider 资源的路径 :这里其值为:table/1该Uri的完整值为: content://lmz.contentprovider.provider/table/1。这也是Uri的一般格式(是不是和网址的格式很像)。但有时我们也会碰到如下 Uri: content://lmz.contentprovider.provider/table。前面说过,Uri有时并未明确地表示出了资源的位置,因此这种Uri表示我们要访问table表中的每一条数据(你也可以认为该Uri明确地指明了我们要访问的是一张数据表)。 以上就是Uri常见的两种类型。我们调用Uri的静态方法:parse(),该方法需要传入一个字符串型的参数,即可将上述字符串转化成Uri对象。现在我们已经确定了Uri,就要开始访问数据了, 这是我们需要使用ContentResolver(内容解决者)对象了,该对象用于访问其它程序的数据(一般都是数据库中的数据): 1.ContentValues对象:用于辅助操作数据表的对象,代表数据表中的一条数据,该对象内部储存着一对对的键值对,其键为String类型,表示数据库的对应的列,而键对应的值就代表了这条数据在该列的值 2.获取ContentResolver对象:调用Context对象的getContentResolver方法即可。 3.操作Uri所标示的数据:调用ContentResolver对象的如下方法即可完成相关操作(附带这些方法的完整参数): 1.insert方法:在指定的Uri(一般代表一张数据表)处插入一条数据,其返回值为插入数据的Uri,其参数为: Uri uri:被操作的数据表的Uri ContentValues values : 被插入的数据 2.delete (Uri url, String where, String[] selectionArgs):删除数据,其返回结果为受影响的数据的条数 3.update(Uri uri, ContentValues values, String where, String[] selectionArgs):更新数据其返回结果为受影响的数据的条数 4.query(uri, projection, selection, selectionArgs, sortOrder):查询Uri所对应的数据,该方法会返回一个Cursor对象,我们遍历Cursor对象就可获得查询结果上面各方法的参数的含义分别为:通过ContentResolver对象我们可以访问手机中的联系人、照片、音乐等数据。下面我我们说说如何使用ContentProvider将本程序中的数据提供给其它程序访问。 ,首先我们需要判断访问数据的Uri的类型。在上面我们了解了Uri一共有两种类型:标示一张数据表的,标示一张数据表中的某一条数据的。在实际中如何表示这两种类型的Uri呢?这时就要用到通配符了。通配符一共有两种: 1. * :表示匹配任意长度的字符串 2. # :表示匹配任意长度的数字因此,两种Uri可分别表示为: content://lmz.contentprovider.provider/table : 标示数据表 content://lmz.contentprovider.provider/table/# : 标示数据表中的某一条数据(假设该表中数据的主键是数字) content://lmz.contentprovider.provider/table/* : 标示数据表中的某一条数据(假设该表中数据的主键是字符串) 安卓系统为我们提供了一个类UriMatcher对象(其内部是一个树形结构),来匹配这两种Uri,其使用方法为: 1.获取实例:直接调用其构造方法即可,该方法需要传入一个参数:我们一般转入UriMatcher类中的静态变量NO_MATCH即可,表示无匹配结果时的返回值 2.添加Uri的种类:调用UriMatcher对象的addUri方法,其参数列表为: String authority :该Uri对应的主机名 String path :该Uri对应的路径 int code : 匹配成功时的返回码 3.匹配Uri:调用match方法即可,该方法接收一个Uri对象,返回匹配结果 接下来我们就要自定义一个ContentProvider对象了,需继承自系统的ContentProvider:
public class MyContentProvider extends ContentProvider{ //Uri的主机名 public static final String AUTHORYTY = "lmz.contentprovider.provider"; //供外部访问的数据表 public static final String TABLE = "table"; public static final int TABLE_DIR = 0;//Uri访问的是一张数据表时的匹配结果 public static final int TABLE_ITEM = 1;//Uri访问的是一条数据时的匹配结果 private static UriMatcher matcher;//判断访问Uri类型的对象 private SQLiteOpenHelper helper;//用于获取数据库实例并操作数据 //对UriMatcher对象进行实例化 static{ matcher = new UriMatcher(UriMatcher.NO_MATCH); matcher.addURI(AUTHORYTY, TABLE, TABLE_DIR);//添加访问数据表的Uri matcher.addURI(AUTHORYTY, TABLE + "/#", TABLE_ITEM);//添加访问数据表的Uri } /** * 对象刚被创建时调用 */ @Override public boolean onCreate() { return false; } /** * 插入数据时调用 */ @Override public Uri insert(Uri uri, ContentValues values) { return null; } /** * 删除数据时调用,首先要利用UriMatcher对象判断Uri的种类 */ @Override public int delete(Uri uri, String selection, String[] selectionArgs) { //在其它方法中也要先做如此的判断 switch(matcher.match(uri)){ case TABLE_DIR: break; case TABLE_ITEM: //调用Uri的 break; default: break; } return 0; } /** * 更新数据时调用,首先要利用UriMatcher对象判断Uri的种类 */ @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { return 0; } /** * 查询数据时调用,首先要利用UriMatcher对象判断Uri的种类 */ @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { return null; } /** * 返回Uri标示的数据的Mime类型(MIME是描述消息内容类型的因特网标准) * 1.必须以vnd开头 * 2.如果该Uri标示的是多条数据,则后接:android.cursor.dir/ * 如果该Uri标示的是多条数据,则后接:android.item.dir/ * 3.最后接上 :vnd.. * 该方法的具体作用本猿猿也不太清楚,有个解释是android系统可以利用该方法识别出Uri标示的是单条还是多条数据 */ @Override public String getType(Uri uri) { return null; }}
关注微信公众号 :猿聚于此,可获得更多相关文章。
更多相关文章
- “罗永浩抖音首秀”销售数据的可视化大屏是怎么做出来的呢?
- Nginx系列教程(三)| 一文带你读懂Nginx的负载均衡
- 不吹不黑!GitHub 上帮助人们学习编码的 12 个资源,错过血亏...
- 一款霸榜 GitHub 的开源 Linux 资源监视器!
- Activity 之间通信
- Android(安卓)Studio 使用Lint检查并去除无用资源文件
- Android(安卓)多个Activity间对象共享
- 安卓开发之解决JS不能调用Android方法填坑
- Android(安卓)用户界面---XML布局