安卓四大组件之Provider

  • 内容提供器介绍##

  • 内容提供器用法##


  • 内容提供器介绍
    内容提供者主要用于在不同的应用程序之间实现数据共享的功能,它提供了一套完整的机制,允许一个程序访问另一个程序中的数据,同时还能保证被访数据的安全性。内容提供其可以选择只对哪一部分数据进行共享。
  • 内容提供器用法
    1)访问其他程序中的数据
    当一个应用程序通过内容提供器对其数据对其数据提供了外部访问接口,任何其他应用程序就可以对这部分数据进行访问。
  • ContentResolver
    若想访问内容提供器中共享的数据,就一定要借助ContentResolver类。ContentResolver 中提供了一系列的方法用于对数据进行 CRUD 操作,其中 insert()方法用于
    添加数据,update()方法用于更新数据,delete()方法用于删除数据,query()方法用于查询数
    据。有没有似曾相识的感觉?没错,SQLiteDatabase中也是使用的这几个方法来进行 CRUD
    操作的,只不过它们在方法参数上稍微有一些区别
    ContentResolver 中的增删改查方法都是不接收表名参数的,而
    是使用一个 Uri 参数代替,这个参数被称为内容 URI。内容 URI 给内容提供器中的数据建立
    了唯一标识符,它主要由两部分组成,权限(authority)和路径(path) 。权限是用于对不同
    的应用程序做区分的,一般为了避免冲突,都会采用程序包名的方式来进行命名。比如某个
    程序的包名是 com.example.app,那么该程序对应的权限就可以命名为 com.example.app.
    provider。路径则是用于对同一应用程序中不同的表做区分的,通常都会添加到权限的后面。
    比如某个程序的数据库里存在两张表,table1 和 table2,这时就可以将路径分别命名为/table1
    和/table2,然后把权限和路径进行组合,内容 URI 就变成了 com.example.app.provider/table1
    和 com.example.app.provider/table2。不过,目前还很难辨认出这两个字符串就是两个内容
    URI,我们还需要在字符串的头部加上协议声明。因此,内容 URI 最标准的格式写法如下:
    content://com.example.app.provider/table1
    content://com.example.app.provider/table2
Uri uri = Uri.parse("content:\\\\com.example/app.provider/table1");

Cursor cursor = getContentResolver().query(uri,projection,selection,selectionArgs,sortOrder);
这些参数和 SQLiteDatabase 中 query()方法里的参数很像,但总体来说要简单一些,毕
竟这是在访问其他程序中的数据,没必要构建过于复杂的查询语句。下表对使用到的这部分
参数进行了详细的解释。

query() 方法参数 对应 SQL 部分 描述
uri from table_name 指定查询某个应用程序下的某一张表
projection select column1, column2 指定查询的列名
selection where column = value 指定 where的约束条件
selectionArgs - 为 where中的占位符提供具体的值
orderBy order by column1, column2 指定查询结果的排序方式

查询完成后返回的仍然是一个 Cursor 对象,这时我们就可以将数据从 Cursor 对象中逐
个读取出来了。 读取的思路仍然是通过移动游标的位置来遍历 Cursor 的所有行, 然后再取出
每一行中相应列的数据,代码如下所示:

if (cursor != null) {
while (cursor.moveToNext()) {
String column1 = cursor.getString(cursor.getColumnIndex("column1"));
int column2 = cursor.getInt(cursor.getColumnIndex("column2"));
}
cursor.close();
}

掌握了最难的查询操作,剩下的增加、修改、删除操作就更不在话下了。我们先来看看
如何向 table1 表中添加一条数据,代码如下所示:

ContentValues values = new ContentValues();
values.put("column1", "text");
values.put("column2", 1);
getContentResolver().insert(uri, values);

可以看到,仍然是将待添加的数据组装到 ContentValues 中,然后调用 ContentResolver
的 insert()方法,将 Uri 和 ContentValues作为参数传入即可。
现在如果我们想要更新这条新添加的数据,把 column1 的值清空,可以借助
ContentResolver 的 update()方法实现,代码如下所示:

ContentValues values = new ContentValues();
values.put("column1", "");
getContentResolver().update(uri, values, "column1 = ? and column2 = ?", new
String[] {"text", "1"});

注意上述代码使用了 selection 和 selectionArgs 参数来对想要更新的数据进行约束, 以防
止所有的行都会受影响。
最后,可以调用 ContentResolver 的 delete()方法将这条数据删除掉,代码如下所示:

getContentResolver().delete(uri, "column2 = ?", new String[] { "1" });
  • 自定义内容提供器
  1. onCreate()
    初始化内容提供器的时候调用。通常会在这里完成对数据库的创建和升级等操作,
    返回 true 表示内容提供器初始化成功,返回 false 则表示失败。注意,只有当存在
    ContentResolver 尝试访问我们程序中的数据时,内容提供器才会被初始化。
  2. query()
    从内容提供器中查询数据。使用 uri 参数来确定查询哪张表,projection 参数用于确
    定查询哪些列,selection 和 selectionArgs 参数用于约束查询哪些行,sortOrder 参数用于
    对结果进行排序,查询的结果存放在 Cursor 对象中返回。
  3. insert()
    向内容提供器中添加一条数据。使用 uri 参数来确定要添加到的表,待添加的数据
    保存在 values 参数中。添加完成后,返回一个用于表示这条新记录的 URI。
  4. update()
    更新内容提供器中已有的数据。使用 uri 参数来确定更新哪一张表中的数据,新数
    据保存在 values 参数中,selection 和 selectionArgs 参数用于约束更新哪些行,受影响的
    行数将作为返回值返回。
  5. delete()
    从内容提供器中删除数据。使用 uri 参数来确定删除哪一张表中的数据,selection
    和 selectionArgs 参数用于约束删除哪些行,被删除的行数将作为返回值返回。
  6. getType()
    根据传入的内容 URI 来返回相应的 MIME 类型。

注意:
getType()方法是所有内容提供器都必须提供的一个方法,用于获取Uri对象所对应的MIME类型。一个内容URI所对应的MIME字符串主要由三部分组成。
1.必须以vnd开头
2.如果内容URI以路径结尾,则后接android.cursor.dir/,如果内容URI以id结尾,则后接android.cursor.item/
3.最后接上vnd.<authority>.<path>
对于 content://com.example.app.provider/table1 这个内容 URI,它所对应的 MIME
类型就可以写成:
vnd.android.cursor.dir/vnd.com.example.app.provider.table1
对于 content://com.example.app.provider/table1/1 这个内容 URI,它所对应的 MIME 类型
就可以写成:
vnd.android.cursor.item/vnd. com.example.app.provider.table1

AndroidManfest.xml配置provider

<provider android:name="com.xxx.MyProvider"
   android:authorities="com.example.databasetest.provider >
</provider>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容