一、废话
好不容易完成出差任务,又被派到另一个地方出差!苦逼的我!年终奖还不给我发,再不发的话我都快没钱坐车回家了!
二、正文
今天内容是ContentProvider——如果做过电话薄应用程序的人肯定都用过这个类,那ContentProvider到底是个什么东西,有什么用,如何用呢?
1、 ContentProvider是个啥?
ContentProvider——内容提供者。它是一个类,这个类主要是对Android系统中进行共享的数据进行包装,并提供了一组统一的访问接口供其他程序调用。这些被共享的数据,可以使系统自己的也可以使我们个人应用程序中的数据。
2、 为什么要有ContentProvider这个类?
在Android中,数据的存储有很多种方式,最常用的就是SQLite和XML文件方式。在不同的应用程序间,其实数据是不能直接被相互访问和操作的,在这种情况下,ContentProvider很好的被用来解决了不同应用程序间数据共享的问题。
其实在Android系统中,已经为我们提供了许多ContentProvider,如:Contacts、Browser、CallLog、Settings等等。那么,Android系统中提供了这么多的ContentProvider,另外还有我们自己公开的共享数据,我们在写程序的时候,怎么才能让我们的应用程序知道去哪儿取、如何取这些数据呢?我们自然的会想到URI。
3、 URI是个啥?在ContentProvider中有什么用处?URI中的几个方法。
URI(Uniform Resource Identifier)——统一资源定位符,URI在ContentProvider中代表了要操做的数据。
在Android系统中通常的URI格式为:content://LiB.cprovider.myprovider.Users/User/21
在万维网访问时通常用的URI格式为:http://www.XXXX.com/AAA/123
- content://——schema,这个是Android中已经定义好的一个标准。我个人一直认为这和我们的http://有异曲同工之妙,都是代表的协议。
- LiB.cprovider.myprovider.Users——authority(主机名),用于唯一标识这个ContentProvider,外部调用者通过这个authority来找到它。相当于www.XXXX.com,代表的是我们ContentProvider所在的”域名”,这个”域名”在我们Android中一定要是唯一的,否则系统怎么能知道该找哪一个Provider呢?所以一般情况下,建议采用完整的包名加类名来标识这个ContentProvider的authority。
- /User/21——路径,用来标识我们要操作的数据。/user/21表示的意思是——找到User中id为21的记录。其实这个相当于/AAA/123。
综上所述,content://LiB.cprovider.myprovider.Users/User/21所代表的URI的意思为:标识LiB.cprovider.myprovider中Users表中_ID为21的User项。
通过上面的介绍,我想大家都知道URI到底是如何标识我们的ContentProvider了,我们就来看看Android系统中为我们提供了些有关操作URI的方法吧。
ContentUris类——操作URI
withAppendedId(builder, id)——在builder最后加上id组成URI。
Uri uri = ContentUris.withAppendedId(User.CONTENT_URI, id);
parseId(uri)——用于从URI中提取出ID值。
long returnID = ContentUris.parseId(User.CONTENT_URI);UriMatcher类——匹配URI
addURI(authority, path, code)——为UriMatcher添加规则,并在匹配成功后返回code值,否则返回构造函数中传入的默认值,一般为UriMatcher.NO_MATCH
参数解释:authority——主机名,path——路径,code——匹配后返回的值
uriMatcher.addURI(Users.AUTHORITY, "User", USER);
4、 ContentProvider中公开的几个方法
- public boolean onCreate():该方法在ContentProvider创建后就会被调用,Android系统运行后,ContentProvider只有在被第一次使用它时才会被创建。
- public Uri insert(Uri uri, ContentValues values):外部应用程序通过这个方法向 ContentProvider添加数据。
- uri——标识操作数据的URI
- values——需要添加数据的键值对
- public int delete(Uri uri, String selection, String[] selectionArgs):外部应用程序通过这个方法从 ContentProvider中删除数据。
- uri——标识操作数据的URI
- selection——构成筛选添加的语句,如"id=1" 或者 "id=?"
- selectionArgs——对应selection的两种情况可以传入null 或者 new String[]{"1"}
- public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs):外部应用程序通过这个方法对 ContentProvider中的数据进行更新。
- values——对应需要更新的键值对,键为对应共享数据中的字段,值为对应的修改值
- 其余参数同delete方法
- public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder):外部应用程序通过这个方法从ContentProvider中获取数据,并返回一个Cursor对象。
- projection——需要从Contentprovider中选择的字段,如果为空,则返回的Cursor将包含所有的字段。
- sortOrder——默认的排序规则
- 其余参数同delete方法
- public String getType(Uri uri):该方法用于返回当前Url所代表数据的MIME类型。
- 如果操作的数据属于集合类型,那么MIME类型字符串应该以vnd.android.cursor.dir/开头,例如:要得到所有user记录的Uri为content:// LiB.cprovider.myprovider.Users /User,那么返回的MIME类型字符串应该为:"vnd.android.cursor.dir/user"。
- 如果要操作的数据属于非集合类型数据,那么MIME类型字符串应该以vnd.android.cursor.item/开头,例如:得到id为21的user记录,Uri为content:// LiB.cprovider.myprovider.Users /User/21,那么返回的MIME类型字符串为:"vnd.android.cursor.item/user"。
5、 如何公开我自己的数据?
看了那么多,如何才能够把我们自己的数据公开出来给别的程序使用呢?
首先,继承ContentProvider并重写它的几个抽象方法
然后,定义我们自己的数据存储(记住,在我们公开的数据中,一定要有个_ID字段,因为在Android中,数据的存储方式是以一个表格的形式存储的,_ID字段唯一标示了每项数据,所以常规做法是将我们的类继承自BaseColumns类,关于这个类请查看官方帮助文档)
然后在AndroidManifest.xml中对我们的Provider进行注册
在AndroidManifest.xml文件中,配置provider节时一定要注意android:name为你的继承自ContentProvider的那个类的类名,android:authorities与你在定义自己的数据存储时所定义的AUTHORITIES字段一定要相等,虽然这个字段值可以随意,但是非常强烈的建议你采用包名加类名的方式类命名。
6、 怎么操作我自己的数据呢?
为了方便我们操作ContentProvider,Android系统为我们提供了ContentResolver类。我们可以使用getContentResolver()方法返回一个ContentResolver对象,并使用它与ContentProvider对应的方法来进行操作。
三、总结
其实在Android中,系统已经为我们提供了许多的ContentProvider了,我们通常情况下是不需要去自定义ContentProvider的。但是,为了更好的理解ContentProvider,自己来实现一个ContentProvider是非常必要的。同时,在Android中,数据的存储方式有很多种,在上面的例子中提到了有SQLite和XML方式,下一篇笔记将介绍如何操作XML文件。