初步理解ContentProvider的工作原理(附简单实例)

创建组件ContentProvider的背景及作用

通过ContentResolver来理解ContentProvider的使用

如何创建ContentProvider和ContentResolver

辅助工具类:Uri,UriMatcher,ContentUris

ContentObserver(监听数据改变类)介绍


创建组件ContentProvider的背景及作用

A:问为什么要创建ContentProvider组件?
么么答:当安卓设备上安装了多个应用之后,这些应用不仅需要访问系统应用,还有可能需要访问第三方应用,此时就需要在不同应用程序之间共享数据,比如小黑-奥巴马的手机上有一个防骚扰软件,可以自由设置来电黑名单,那个这个防骚扰软件就需要访问电话管理器软件,他提取电话管理器相关数据,比如骚扰电话的号码,联系人等。
对于这种需要在不同应用之间共享数据(提供本应用的数据供其他软件访问甚至修改)的需求,安卓系统给我们提供了ContentProvider组件。

B:问一个应用程序如何通过ContentProvider提供数据给其他应用查询或者修改的?
么么答:首先ContentProvider和Activity/Service/BroadcastReceiver一样,对于继承了基类的各个实例子类都需要再Manifest 中进行配置(如何配置见后面,很简单),当一个应用程序需要把自己的数据暴露给其他程序使用时,该应用程序就可以通过ContentProvider来实现,其他应用程序就可以通过我们后面将介绍的一个类:ContentResolver来取出ContentProvider中暴露的数据,注意:只要提供了供外部访问数据的ContentProvider,那么其他应用都可以通过这个“地址”或者叫“接口”来访问数据提供者,进行增删改查等操作,而不管提供者是否启动。


通过ContentResolver来理解ContentProvider的使用

初步理解ContentProvider的工作原理(附简单实例)_第1张图片
备注:这里的Uri详细介绍请看下面的介绍
其实很简单:就像组件Activity隐士启动一样,提供数据给其他应用A访问的应用B给出了一个类似网址一样的Uri,凡是根据这个Uri都能访问到应用B的数据,而且为了更加方便的访问,应用B都会在配置文件manifest里面给出自己的网址Uri,同样访问其他应用数据的应用程序A可能需要访问多个应用程序,但一个调用只能有一个Uri,一个Uri对应一个提供外部数据访问的应用。表面上是A根据网址直接增删改查应用B,其实都是根据Uri直接转到应用B中对应的增删改查方法,根据应用A提供的参数来执行具体的行为。


如何创建ContentProvider和ContentResolver

A:如何创建ContentProvider呢?
根据前面的解释,我们知道ContentProvider其实并没有傻瓜一样把自己的数据全部传到存储器中,况且这样也是不可能的,而是提供一个接口,根据这个接口直接到ContentProvider的应用中增删改查,好,下面介绍如何创建一个 ContentProvider:
第一步:提供外部数据访问的应用程序创建自己的ContentProvider,这个ContentProviderDemo需要继承基类ContentProvider
第二部:在配置文件manifest中注册自己,包括name(注册类地址),authorities(接口的地址Uri),exported(是否被访问数据),如下:

<application  .....>
        <provider
            android:name=".ContentProviderDemo"
            android:authorities="com.example.contentprovider"
            android:exported="true"  />
application>

通过配置文件就已经把ContentProviderDemo的访问地址暴露给其他数据访问者了,其他程序可以通过ContentResolver来根据这个地址访问ContentProvider了。

在创建了应用程序的ContentProvider和在配置文件进行Uri访问地址注册之后,我们再到具体的继承了ContentProvider的子类ContentProviderDemo中,根据数据访问的增删改查来看看具体的方法和参数,注意,这里的增删改查与实际的数据库操作增删改查方法名称一样,但是参数不同。

方法1:

//当第三方应用第一次访问ContentProvider时,该ContentProviderDemo就会被创建,被创建之后立即回调onCreate()方法
public boolean onCreate(){}

方法2:

//根据该Uri插入values对应的数据,注意,这个方法必须依托实际的SQL语句进行操作,他不是实际的数据库操作方法,需要在方法内手动添加sql语句,同时这里的Uri传入的是并非仅是该子类注册的authorities对应的Uri,这里的参数Uri一般在注册的Uri的基础上添加了资源部分,具体见下面介绍的Uri工具类
public Uri insert(Uri uri,ContentValues values){}

方法3:

//根据uri删除selection条件所匹配的全部记录
public int delete(Uri uri,String where,String[]whereArgs)
    参数:uri增加了资源部分的Uri
    参数:where满足该参数的记录将删除
    参数:whereArgs 用于为where传入参数

方法3:

//根据Uri修改where参数所匹配的记录,这里的参数和上面的作用类似,不再介绍了
public int update(Uri uri,ContentValues values,String where,String[] whereArgs,){}

方法4:

//根据Uri查询出where条件所匹配的全部记录,project是一个列名列表,表明只选择出指定的数据列
public Cursor query(Uri uri,String [] projection,String where,String[]whereArgs,String sortOrder){}
//例如:Cursor cursor = contentResolver.query(Words.word.DICT_CONTENT_URI,null,"words like ? or detail like ?",new String[]{"%"+key+"%","%"+key+"%"},null);

方法5:

//用于返回当前Uri代表的数据的MIME类型,关于MIME在下面介绍
public String getType(Uri uri){}
如果Uri是多条记录(words):return vnd:android.cursor.dir/开头
如果Uri是单挑记录(word/#):return vnd:android.cursor.item/开头

好了,上面介绍了继承了ContentProvider 的子类需要重载的5个方法,下面介绍取出操作的关键类:ContentResolver

B:如何创建ContentResolver?

1、如何获取ContentResolver()方法?
通过Context的ContentResolver()方法可以取出ContentResolver对象,既然Context能取出,那么Activity、Service都可以通过getContentResolver()方法取出ContentResolver对象

2、取出当前的 ContentResolver对象之后如何操作数据呢?
既然取出了相应的ContentResolver对象,那么就调用ContentResolver.query()/insert()/update()/delete()等方法进行操作数据,记住,这里的加载顺序是:ContentResolver的增删改查方法根据Uri匹配到对应的数据提供者ContentProvider,然后自动调用ContentProvider中的对应的增删改查方法。

辅助工具类:Uri,UriMatcher,ContentUris

参考文章:http://blog.csdn.net/miao_dingxiao/article/details/53198923

你可能感兴趣的:(android)