Android必知必会的四大组件 -- ContentProvider篇

前言

做为四大组件之一,它的地位绝对不允许轻视的。可是咱们在哪里有用到过他呢?其实很简单,你在使用app时,是否是常常的会询问你是否开启通信录的访问,若是你赞成了,这个时候ContentProvider就发挥了他的做用。java

思惟导图

使用方法

如下经过对通信录的操做让读者来更清晰的了解。 可是共享的数据不该该被咱们随意的更改,若是有这样的须要,把这些数据存储在本地,而后再进行这样的操纵更为合适,因此下方的演示代码只包含了查询的功能。不过由于调用外部的数据,通常来讲须要权限申请。android

我已经在Android工具包中已经集成了权限申请的工具类。git

// 数据查询
try (Cursor cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null)) {
        while (cursor.moveToNext()) {
                String name = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
                String number = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                Log.e(TAG, name + " ;" + number);
            }
} catch (Exception e) {
            e.printStackTrace();
}
复制代码

文件共享的基础

其实在ContentProvider中使用的通讯机制依旧是Binder,而文件定位则是经过URI的方式来完成,因此主讲的一部份内容就是URI的格式解析。github

URI

格式:[scheme:][//host:port][path][?query]
复制代码

这一个URI的格式,为了方便起见,咱们直接拿一个域名来分析它。数据库

》》例题《《bash

连接地址:juejin.im/user/5e2659…app

  1. scheme:https,也就是协议
  2. host:juejin.im,域名地址
  3. port:默认80,端口号
  4. path:/user/5e2659e15188254d95242d4b,文件路径/控制器路径
  5. query:好比 ?userId=x&message=y,就是咱们javaWeb中的一些请求数据。

固然在咱们的ContentProvider存在必定的误差。ide

文件位置:content://com.clericyi.file/message/id工具

  1. scheme:content://,这是Android的固定路径
  2. authority:com.clericyi.file,也就是用于标示惟一的ContentProvider
  3. path:message,也就是对应的表名
  4. id:对应表中的数据

帮助工具

UriMatcher

这是一个内置的URI工具,他一共只提供了两个开放方法addURI()match(),这是一个用于帮助匹配ContentProviderURI的方法,针对的是除去id前半段匹配。post

// 用法
UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
String authority = "com.clericyi.file";
String path = "message";
int URI_CODE = 1;
// 将URI和URI_CODE关联
uriMatcher.addURI(authority, path, URI_CODE);
// 用于获取对应的URI_CODE
uriMatcher.match(Uri.parse("content://com.clericyi.file/message"))
复制代码

ContentUris

一样是一个内置的工具类,提供的方法有parseId()appendId()withAppendedId()removeId(),针对的就是id

Uri uri = Uri.parse("content://com.clericyi.file/messag");
// 链接id
uri = ContentUris.withAppendedId(uri, CODE);
// 去除id
uri = ContentUris.removeId(uri);
// 获取id
long num = ContentUris.parseId(uri);
复制代码

ContentProvider代码流程导读

工做流程:

从上文中的电话簿号码查询入手
(1)获取一个ContentResolver,并调用query(),内部参数不少,基本和数据库查询的参数保持一致。
(2)在query()方法中会调用到acquireUnstableProvider(uri)的方法,而返回值IContentProvider,对应就是一个Binder机制
(3)内部经过对uri的一些解析,找获得对应的文件,而后转化成Cursor游标
(4)经过游标的滑动读取,就转化成了咱们的数据
复制代码

query()内部参数分析

  • uri:位置暴露的惟一表示。
  • projection:返回列(字段)
  • selection:设置条件,至关于数据库中的where
  • selectionArgs:和selection联合使用,用于替换selection中的 ?
  • sortOrder:排列顺序,至关于数据库中的order by
所有参数使用实例:
contentResolver.query(android.provider.ContactsContract.Contacts.CONTENT_URI
    , new String[]{android.provider.ContactsContract.Contacts.DISPLAY_NAME}
    , android.provider.ContactsContract.Contacts.DISPLAY_NAME + "=?"
    , new String[]{"小易"}
    , android.provider.ContactsContract.Contacts.DISPLAY_NAME + " DESC"); // 中间存在空格,默认为ASC,升序。
复制代码

最后的话这片文章就不写关于联合Database的使用了,应该容易冗长,专门找了一篇文章给读者们拿来专门学习ContentProvider的使用。跳转连接

另外也算是个人一种突破,毕竟一天发了四篇博客,虽然两篇其实我只是重构了一下,可是着实仍是有点累的。

以上就是个人学习成果,若是有什么我没有思考到的地方或是文章内存在错误,欢迎与我分享。


相关文章推荐:

Android必知必会的四大组件 -- Activity篇

Android必知必会的四大组件 -- Broadcast Receiver篇

Android必知必会的四大组件 -- Service篇

相关文章
相关标签/搜索