ContentProvider、ContentResolver

基础

        对内容提供者的访问,是通过ContentResolver来完成的。某个应用通过ContentProvider向外提供访问的接口,访问者通过ContentResolver进行访问。

        连接ContentProvider与ContentResolver的就是Uri。因此,想要准确地访问某个内容提供者,写对Uri是非常重要的事情。其Uri的拼写规则为: Uri必须 “content://”开头

        当自己写完一个内容提供者之后,需要在清单文件中进行注册,此时便需要指定authorities属性,假设该属性的值是x。那么通过ContentResolver访问该ContentProvider时的Uri便为:“content://x”。因此,可以通过查看系统的源码,从而拼出系统内容提供者的Uri。只需要用"content://"拼上该内容提供者的authorities值即可。

        以上是Uri的基本形式。但有些时候会发现Uri会是“content://x/yyy”的形式,也就是Uri后面指定的path。

对于path的理解:

        我们可以把yyy看成一个指令,用于指使ContentProvider执行什么样的操作,或者是操作哪一个数据结构(大部分情况下是数据库)等。

        下面以android系统的短信内容提供者为例,首先看\providers\TelephonyProvider中的清单文件,其中有一个SmsProvider,它的配置是:

<provider
            android:name="SmsProvider"
            android:authorities="sms"
            android:exported="true"
            android:multiprocess="true"
            android:readPermission="android.permission.READ_SMS"
            android:writePermission="android.permission.WRITE_SMS" />

        因此,我们要想通过ContentResolver访问SmsProvider,那么Uri便可以写成:“content://sms”。

        再看SmsProvider中的具体代码:

在静态代码块中,为UriMatcher添加了一系列的Uri。截取前三个如下:

static {
		sURLMatcher.addURI("sms", null, SMS_ALL);
		sURLMatcher.addURI("sms", "#", SMS_ALL_ID);
		sURLMatcher.addURI("sms", "inbox", SMS_INBOX);

接着看一个SMS_INBOX的使用:

        在query,insert,update三个方法中都有一个case SMS_INBOX:。以query方法为例,在case SMS_INBOX情况下,它最终会执行:

private void constructQueryForBox(SQLiteQueryBuilder qb, int type) {
		qb.setTables(TABLE_SMS);
		if (type != Sms.MESSAGE_TYPE_ALL) {
			qb.appendWhere("type=" + type);
		}
	}

        从上面的代码可以看出,SMS_INBOX只不过是为sql语句添加一个查询条件而已。

        同理当取成case SMS_SENT: case SMS_DRAFT等值时,也是会执行上面的方法,只不过将参数type的值给换了,也就是查询条件给更换了。

        因此,从上面可以看出当在content://x/yyy后面path的一个作用就是执行不同的操作

同理,当我们再看到sURLMatcher.addURI("sms", "raw",SMS_RAW_MESSAGE);,从而跳跃SMS_RAW_MESSAGE时,会发现它是将要操作的表给换了。即当uri为content://sms/raw时,它改变了ContentProvider要操作的表。

        综上所述:content://x/yyy后面的path只是影响着要执行sql语句。而具体会执行什么样的内容,自己应该通过UriMatcher. addURI()方法中的哪一个拼到content://x后面,就需要根据源码来看,看哪一个是自己需要的操作。

ContentResolver

        它是用来操作ContentProvider的,后者提供了CRUD方法,而可以用前者调用CRUD。这些CRUD操作,最终会调用与它Uri相匹配的ContentProvider的。而且在ContentResolver中还可以注册内容观察者。用registerContentObserver()方法即可。也可以通过调用notifyChange()等方法来通知相应的内容观察者。从而可以调用内容观察者中的方法。








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值