Content Provider 详解
几个概念:Cursor、 Content provider 、 Uri 、contentresolver
1、
Cursor : 个人理解为数据库中的一行数据,它是每行数据的集合。它是一个类。通过它的一系列方法,我们可以对数据库中的每行进行定位,我们还可以知道每一列的信息。比如:
cursor(游标).moveToFirst(),表示定位到第一行,然后我们通过其他方法可以知道每列的名称,每列的数据类型等。
2、
Content Provider :内容提供者,我们一个application中的其他类假如想操作数据库中的数据的话,就可以直接对此进行操作,而避免了对数据库进行直接操作,再说了,数据库这些个东西有权限要求的,我们不可能把数据库直接暴露出来,所以,通常采用这种形式。其实他就是一个提供数据访问的网站,我们要访问它的话,就得知道他的域名。 android:authorities . 在minifest.xml中配置如下:(包含两个部分,name 与 anthorities)
<provider android:name=".PersonProvider" android:authorities=
"com.sharpandroid.providers.personprovider"/>
当某个应用,可能是外部的,可以通过这两个属性来找到这个Content Provider了。
Content Provider 支持在多个应用中存储和读取数据。这也是跨应用共享数据的唯一方式。在android系统中,没有一个公共的内存区域,供多个应用共享存储数据。
3、
Uri: 这个东西就是 提供者提供数据的详细地址,到底是哪些数据,用此来对数据进行过滤操作。假如说,Content Provider是一个DNS,域名的话。那么Uri可以认为是IP地址,我们通过此IP地址找到我们所需要的数据。知道了它,就知道了数据在哪,然后通过调用某个方法,返回一个Cursor对象。数据包含在这个其中。
它有几个部分组成: content://com.sharpandroid.provider.personprovider/person/2
其中,scheme:content 表示这个数据被一个content类型的数据(内容提供者)所控制。
authrities: com.sharpandroid.provider.personpervider表示权限部分,就是contentprovider的域名部分。。
path:用来请求数据类型的路径。person/2 。请求的是person/2,还可以是school/student等。
ID:被请求特定记录的ID。
还有一点需要注意,需要被数据不一定来自数据库,还可以来自其他地方,比如说XML,文本等。
Uri.parse()这个方法可以将字符串解析为Uri的形式。
我们一般通过UriMather类用来对我们 我们传递过来的IP进行自动匹配。
private static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
private static final int PERSONS = 1;
private static final int PERSON = 2;
private DatabaseHelper databaseHelper;
static{
matcher.addURI("com.sharpandroid.providers.personprovider",
"person", PERSONS); //对特定的值进行匹配,成功返回1.
matcher.addURI("com.sharpandroid.providers.personprovider",
"person/#", PERSON);//#表示通配符,如果匹配成功,返回匹配码2.
}
4、
contentresovler:
那么我们该如何使用contentprovider呢?
我们一般通过contentresolver来对内容提供者提供的数据进行操作。
这个类提供了与Content Provider 相同的四个方法,增删改查方法。
如果需要查询contentprovider数据集的特定记录(行),还需要知道该记录的ID的值。
构建查询
查询就是输入URI等参数,其中URI是必须的,其他是可选的,如果系统能找到URI对应的contentprovider将返回一个Cursor对象。
可以通过ContentResolver.query()或者Activity.managedQuery()方法。两者的方法参数完全一样,查询过程和返回值也是相同的。
其他注意点:
query()方法,返回值是Cursor实例,用于迭代请求的数据。Cursor是一个接口。android为该接口提供了一些只读的(和 JDBC的ResultSet不一样,后者还提供可写入的可选特性)Cursor实现。比如SQLiteCursor,可迭代SQLite数据库中的数据。可以通过SQLiteDatabase类的query()方法获取到该Cursor实例。还有其他的Cursor实现,比如 MatrixCursor,用于数据不是存储在数据库的情况下。
因为Contentprovider可能被多个ContentResolver对象在不同的进程和线程中调用,因此实现Contentprovider必须考虑线程安全问题。
作为良好的习惯,在实现编辑数据的代码中,要调用ContentResolver.notifyChange()方法,通知那些监听数据变化的监听器。
在实现子类的时候,还有一些步骤可以简化Contentprovider客户端的使用:
定义public static final Uri常量,名称为CONTENT_URI:
public static final UriCONTENT_URI =
Uri.parse("content://com.example.codelab.transportationprovider");
如果有多个表,它们也是使用相同的CONTENT_URI,只是它们的路径部分不同。

也就是说红色框部分是一致的。
定义返回的列名,public static final,列名的值,比如使用SQLite数据库作为存储,对应表的列名。
在文档中要写出各个列的数据类型,便于使用者读取。
如果需要处理新的MIME数据类型,比如通过Intent的方式,并且带data的mimeType(参见总结一下Intent概念),那么需要在ContentProvider.getType()方法中进行处理,参见编写完整的Contentprovider示例编写一个getType方法部分。
如果处理数据库表中超大的数据,比如很大的位图文件,一般存在文件系统中,可以参照在contentprovider中使用大型二进制文件,这样第三方的contentprovider使用者,可以访问不属于它权限的文件,通过contentprovider做代理。
声明 Content Provider
创建ContentProvider后,需要在manifest文件中声明,android系统才能知道它,当其他应用需要调用该ContentProvider时才能创建或者调用它。
语法类似:
<providerandroid:name="com.easymorse.cp.MyContentProvider"
android:authorities="com.easymorse.cp.mycp"></provider>
android:name要写ContentProvider继承类的全名。
android:authorities要写和CONTENT_URI常量的B部分(见上面图)。
注意不要把上图C和D部分加到authorities中去。authorities是用来识别ContentProvider的,C和D部分实际上是ContentProvider内部使用的。
Content Provider 详解的更多相关文章
- Content Providers详解
今天仔细阅读了一遍Content Providers的官方API文档,总结了一下Android中Content Providers的用法. 各种类型的Content Provider对一个结构化的数据 ...
- android 四大组件详解
这个文章主要是讲Android开发的四大组件,本文主要分为 一.Activity详解二.Service详解三.Broadcast Receiver详解四.Content Provider详解外加一个重 ...
- AndroidMainfest详解
基于TV settings和SettingsProvider Android启动模式对activity行为的影响 AndroidManifest.xml文件详解 Manifest文件中,applica ...
- 入职小白随笔之Android四大组件——内容提供器详解(Content Provider)
Content Provider 内容提供器简介 内容提供器(Content Provider)主要用于在不同的应用程序之间 实现数据共享的功能,它提供了一套完整的机制,允许一个程序访问另一个程序中的 ...
- content = "IE=edge,chrome=1" 详解
content = "IE=edge,chrome=1" 详解 < meta http-equiv = "X-UA-Compatible" content ...
- 【META http-equiv="Content-Type" Content="text/html; Charset=*】意义详解
[META http-equiv="Content-Type" Content="text/html; Charset=*]意义详解 META,网页Html语言里Head ...
- ActionBar详解
转: 一.ActionBar介绍 在Android 3.0中除了我们重点讲解的Fragment外,Action Bar也是一个非常重要的交互元素,Action Bar取代了传统的tittle bar和 ...
- Android UI组件----AppWidget控件入门详解
Widget引入 我们可以把Widget理解成放置在桌面上的小组件(挂件),有了Widget,我们可以很方便地直接在桌面上进行各种操作,例如播放音乐. 当我们长按桌面时,可以看到Widget选项,如下 ...
- Android proguard 详解
本文转载于:http://blog.csdn.net/banketree/article/details/41928175 简介 Java代码是非常容易反编译的.为了很好的保护Java源代码,我们往往 ...
随机推荐
- 精通CSS高级Web标准解决方案(1-3 规划、组织与维护样式表)
对文档应用样式 对代码进行注释/*......*/ 结构性注释 自我提示 删除注释.优化样式表 样式指南:解释代码与站点的视觉设计是如何组织在一起的 站点结构.文件结构.命名规则 编码标准:(X)ht ...
- 运行Android程序出错:The connection to adb is down, and a severe error has occured
调试Android程序时候,报错如下: [2013-02-21 15:41:06 - MainActivity] ------------------------------[2013-02-21 1 ...
- Model View Controller(MVC) in PHP
The model view controller pattern is the most used pattern for today’s world web applications. It ha ...
- POJ 1690 (Your)((Term)((Project)))
(Your)((Term)((Project))) Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 2912 Accept ...
- angular2 通过指令限制输入
最近在写一个表单,有些输入框只能输入数字,单又不想每次写表单的时候,都要去验证输入的是不是数字, 那么就想到直接限制只能输入数字,通过指令实现 这里需要注意的是,不只更改DOM的值,如果input为数 ...
- Swift 3:新的访问控制fileprivate和open
在swift 3中新增加了两种访问控制权限 fileprivate和 open.下面将对这两种新增访问控制做详细介绍. fileprivate 在原有的swift中的 private其实并不是真正的私 ...
- iOS学习笔记45-Swift(五)协议
一.Swift协议 协议是为方法.属性等定义一套规范,没有具体的实现,类似于Java中的抽象接口,它只是描述了方法或属性的骨架,而不是实现.方法和属性实现还需要通过定义类,函数和枚举完成. 1. 协议 ...
- LCT(Link-Cut Tree)
Link-cut tree(LCT)[可以理解为树链剖分+splay] 给出如下定义: access(x):访问x节点 perferred child:若以x为根的子树中最后被访问的节点在以x的儿子y ...
- 《常见问题集》Maven
1.Maven Eclipse插件要不要安装? [解决方法] 打开你的Eclipse,如果已经有Maven了就不用装插件了. 方法一:没有的话或者下载最新的Eclipse(maven插件,eclips ...
- 系统虚拟内存的理解 转载自http://blog.csdn.net/do2jiang/article/details/4690967
在进入正题前先来谈谈操作系统内存管理机制的发展历程,了解这些有利于我们更好的理解目前操作系统的内存管理机制. 一 早期的内存分配机制 在 早期的计算机中,要运行一个程序,会把这些程序全都装入内存,程序 ...