Android四大组件之ContentProvider

Android四大组件之ContentProvider

为了在应用程序之间沟通数据,Android提供了ContentProvider,它是差异应用程序之间开始展览数据沟通的正儿八经API,当贰个应用程序供给把温馨的数码暴光给别的程序行使时,该应用程序就可由此提供ContentProvider来达成;别的应用程序就可通过ContentResolver来操作ContentResolver揭露的多少。

  1. ContentProvider:差别采纳之间进行数据调换的标准API,当1个应用程序要把自身的数额揭示给此外应用时,就足以由此ContentProvider来完毕,其余应用程序通过ContentResolver操作ContentProvider暴漏的多寡
  2. 应用程序通过ContentProvider暴露了祥和的数码操作接口,那么不论是采纳是不是运转,其余应用都能够透过该接口来操作该应用程序的里边数据

ContentProvider简介

ContentProvider是例外应用程序之间展开数据沟通的正儿八经API,ContentProvider以某种Uri的形式对外提供数据,允许别的应用访问或改动数据;其余应用程序使用COntentResolver依据Uri去拜谒操作钦定数量。

只要有些应用程序通过COntentProvider暴光了友好的多少操作接口,那么不管该应用程序是不是运营,别的应用程序都可经过该接口来操作该应用程序的里边数据,包蕴扩展数据、删除数据、修改数据、查询数据等。

ContentResolver只是提供数据的拜访接口,并不是像网站相同对外提供全体的页面。开发三个ContentProvider的步调如下所示:

  1. 概念自身的ContentProvider类,该类供给继承Android提供的ContentProvider基类。
  2. 向Android系统登记ContentProvider,即在AndroidManifest.xml文件中登记这几个ContentProvider,就想注册Activity一样。注册ContentProvider时要求为它绑定八个Uri。

除了这么些之外,本人定义的ContentProvider类还亟需提供如下多少个措施:

  • public boolean
    onCreate():
    该办法在ContentProvider创设后会被调用,当其余应用程序第三次访问ContentProvider时,该ContentProvider会被创建出来,并立刻回调该onCreate()方法。
  • public Uri insert(Uri uri ,ContentValues
    values):
    依照该Uri插入values对应的数据。
  • public int delete(Uri uri ,String selection ,String[]
    selectionArgs):
    依据Uri删除selection条件所匹配的全方位记下。
  • public int update(Uri uri ,ContentValues values ,String selection
    ,String[]
    selectionArgs):
    据悉Uri修改selection条件所匹配的全体记下。
  • public Cursor query(Uri uri ,String[] projection ,String
    selectionn ,String[] selectionArgs ,String
    sortOrder):
    听别人说Uri查询出selection条件所匹配的全数记录,在那之中projection正是一个列名列表,注明只选择出钦点的数据列。
  • public String getType(Uri
    uri):
    该办法用于重临当前Uri所代表的数目标MIME类型。假诺该Uri对应的数码大概蕴含多条记下,那么MIME类型字符串应该以vnd.android.cursor.dir/开始;假若该Uri对应的多少只含有一条记下,那么MIME类型字符串应该以vnd.android.cursor.item/伊始。
  1. ContentProvider以某种Uri的花样对外提供数据,开发ContentProvider的步子:

Uri简介

ContentProvider要求的Uri与互连网的UENVISIONL类似,例如如下Uri:

content://org.crazyit.providers.dictprovider/words

它能够分为如下三局地:

  • content://:以此局地是Android的ContentProvider规定的,就像上网的磋商私下认可是http://一样。暴露ContentProvider、访问ContentProvider的协议默认是content://。
  • org.crazyit.providers.dictprovider:以此局地正是COntentProvider的authorities。系统正是由这么些片段来找到操作哪个ContentProvider的。只要访问钦命的ContentProvider,这一个部分就是一向的,
  • words:财富部分(或然说数据部分)。当访问者须要拜访差别财富时,这一个局地是动态改变的。

为了将2个字符串转换来Uri,Uri工具类提供了parse()静态方法。例如,如下代码即可将
字符串转换为Uri:

Uri  uri = Uri.parse("content://org.crazyit.providers.dictprovider/word/2")

概念自身的ContentProvider类,继承自Android提供的ContentProvider基类

ContentResolver操作数据

ContentProvider的功用是揭露可供操作的数量;别的应用程序则透过ContentProvider来操作ContentProvider所暴光的数目,ContentResolver也便是HttpClient。
Context提供了如下方法来获取ContentResolver对象:

  • getContentResolver():获取该利用暗中同意的ContentResolver对象。

比方在先后中赢得了ContentResolver对象之后,接下去就可调用ContentResolver的如下方法来操作数据了。

  • insert(Uri uri ,ContentValues
    values):
    向Uri对应的ContentProvider中插入values对应的数量。
  • delete(Uri uri ,String where ,String[]
    selectionArgs):
    去除Uri对应的ContentProvider中where提交匹配的数额。
  • update(Uri uri ,ContentValues values ,String where ,String[]
    selectionArgs):
    更新Uri对应的ContentProvider中where提交匹配的多寡。
  • query(Uri uri ,String[] projection ,STring selection ,String[]
    selectionArgs ,String
    sortOrder):
    查询Uri对应的ContentProvider中where提交匹配的数目。

一般的话,ContentProvider是单实例格局的,当七个应用程序通过ContentResolver来操作ContentProvider提供的数目时,ContentResolver调用的数目操作将会委托给同三个ContentProvider处理。

向Android系统注册,也便是在AndroidManifest.xml中登记,注册ContentProvider时须求为它绑定三个Uri,并制定authorities属性,注意name值中有点,exported代表是还是不是允许别的使用调用

ContentProvider与ContentResolver的关系

从ContentResolver、ContentProvider和Uri的关系来看,无论是ContentResolver,照旧ContentProvider,它们所提供的增加和删除改查方法的率先个参数都以Uri。也正是说,Uri是ContentProvider和ContentResolver进行数据沟通的标识。ContentResolver对点名Uri执行增加和删除改查的多少操作,但Uri并不是真正的多寡基本,因而这一个增加和删除改查操作会委托给该Uri对应的ContentProvider来完成。

ContentProvider、Uri、ContentResolver三者之间的涉及如下图所示:

0.jpg

以内定Uri为标识,ContentResolver能够兑现“直接调用”ContentProvider的增加和删除改查方法:

  1. 当A应用调用ContentResolver的insert()方法时,实际上也等于调用了该Uri对应的ContentProvider的insert()方法。
  2. 当A应用调用ContentResolver的update()方法时,实际上也即是调用了该Uri对应的ContentProvider的update()方法。
  3. 当A应用调用ContentResolver的delete()方法时,实际上约等于调用了该Uri对应的ContentProvider的delete()方法。
  4. 当A应用调用ContentResolver的query()方法时,实际上相当于调用了该Uri对应的ContentProvider的query()方法。

<Provider android:name=”.DictProvider”
android:authorities=”org.crazyit.providers.dictprovider”  
android:exported=”true” />

开发ContentProvider子类

支付ContentProvider只要如下两步:

  1. 开发八个ContentProvider子类,该子类需求达成query()、insert()、update()和delete()等艺术。
  2. 在AndroidManifest.xml文件中登记该ContentProvider,内定android:authorities属性。

DictProvider还需兑现如下的法门:

配置ContentProvider

只要为<applicaton…/>成分添加了<provider…/>子成分即可配置ContentProvider。例如如下的布局地分:

<provider
        android:name=".FirstProvider"
        android:authorities="org.crazyit.providers.firstprovider"
        android:exported="true"/>

配置ContentProvider时平常钦定如下属性:

  • name:点名该ContentProvider的完毕类的类名。
  • authorities:点名该ContentProvider对应的Uri(也就是为该ContentProvider分配3个域名。)
  • android:exported:点名该ContentProvider是或不是同意任何应用调用。假使将该属性设为false,那么该ContentProvider将分裂意其余使用调用。

为了显著ContentProvider实际能处理的Uri,以及明显每种方法中Uri参数所操作的数据,Android系统提供了UriMatcher工具类,主要提供了之类四个点子:

  • void addURI(String authority ,String path ,int
    code):
    该措施用于向UriMatcher对象注册Uri。个中authority和path组合成三个Uri,而code则代表该Uri对应的标识码。
  • int match(Uri
    uri):
    传闻前边注册的Uri来判定内定Uri对应的标识码。假使找不到格外的标识码,就会回来-1。

Android还提供了2个ContentUris工具类,它是1个操作Uri字符串的工具类,提供了之类七个工具方法:

  • withAppendedId(uri , id):用来为路径加上ID部分。
  • parseId(uri):用来从内定Uri中分析出所涵盖的ID值。
  • onCreate:其余应用程序第二回访问ContentProvider时,该ContentProvider会被创立出来,并霎时调用onCreate方
  • Uri
    insert(Uri,ContentValues)方法:依照该Uri插入ContentValues对应的数据
  • int
    delete(Uri,String,String[])方法:依据Uri删除select条件所匹配的万事记录
  • int
    update(Uri,ContentValues,String,String[])方法:依照Uri修改满足selection条件所匹配的保有记录
  • Cursor
    query(Uri,String[],String,String[],String):恩局Uri查询出满意select条件所匹配的全体记下,个中projection正是3个列名列表,申明只选用出内定的列
  • String
    getType(Uri):重回当前Uri所代表的数码的MIME类型,假如Uri对应数据包括多条记下,那么MIME类型字符串应该是以vnd.android.cursor.dir 开端,要是只对应一条记下,那么再次来到的MIME类型字符串应该以vnd.android.cursor.item初叶

操作系统的ContentProvider

Android系统本人提供了大气的ContentProvider,使用ContentResolver操作系统的ContentProvider数据的步骤也是两步:

  1. 调用Context的getContentResolver()获取ContentResolver对象;
  2. 依据供给调用ContentResolver的insert()、delete()、update()和query()方法操作数据。

Android系统用于管理挂钩人的ContentProvider的多少个Uri如下:

  • ContactsContract.Contacts.CONTENT_URI:治本挂钩人的Uri。
  • ContactsContract.CommonDataKinds.Phone.CONTENT_URI:管制挂钩人的电话机的Uri。
  • ContactsContract.CommonDataKinds.Email.CONTENT_URI:治本挂钩人的E-mail的Uri。

Android为多媒体提供的ContentProvider的Uri如下所示:

  • MediaStore.Audio.Media.EXTERNAL_CONTENT_URI:储存在外表存款和储蓄其上的音频文件内容的ContentProvider的Uri。
  • MediaStore.Audio.Media.INTERNAL_CONTENT_URI:存款和储蓄在二弟大内存上的音频文件内容的ContentProvider的Uri。
  • MediaStore.Images.Media.EXTERNAL_CONTENT_URI:仓库储存在外存上的图纸文件内容的ContentProvider的Uri。
  • MediaStore.Images.Audio.Media.INTERNAL_CONTENT_URI:仓库储存在手提式有线电话机里面存款和储蓄器上的图片文件内容的ContentProvider的Uri。
  • MediaStore.Video.Media.EXTERNAL_CONTENT_URI:积存在外部存款和储蓄器上的录制文件内容的ContentProvider的Uri。
  • MediaStore.Video.Audio.Media.INTERNAL_CONTENT_URI:储存在手提式无线电话机内部存储器上的录像文件内容的ContentProvider的Uri。

ContentProvider
Uri的格式:content://authority/数据部分,autority类似于Url中域名的功力,数据部分是可变的,前边是定位的格式,要注意数据部分的解释,因为一个ContentProvider或者提供五个Uri
对应差异数量的拜会,但content://authority部分不变

监听ContentProvider的多少变动

在事先的介绍中,只要导致了ContentProvider数据发生了变更,程序中就调用如下代码:

getContext().getContentResolver(),notifyChange(uri ,null);

为了在应用程序中监听ContentProvider数据的改观,需求利用Android提供的ContentObserver基类。监听ContentProvider数据变动的监听器须求继续ContentObserver类,同仁一视写该基类所定义的onChange(boolean
selfChange)方法–当所监听的ContentProvider数据发生变更时,该onChange()方法将会被触发。

为了监听钦点ContentProvider的数量变动,要求经过ContentResolver向钦赐Uri注册ContentObserver监听器。ContentResolver提供了如下方法来注册监听器:

  • registerContentObserver(Uri uri , boolean notifyForDescendents ,
    ContentObserver observer)

本条点子的几个参数分别代表:

  • uri:该监听器所监听的ContentProvider的Uri。
  • notifyForDescendents:即使该参数设为true,借使注册监听的Uri为content://abc,nameUri为contetn://abc/xyzcontent://abc/xyz/foo的多寡变动时也会触发该监听器;尽管设为false,那么唯有content://abc的数码发生变动时才会触发该监听器。
  • observer:监听器实例。

 数据的储存系统能够由开发人士任意支配,一般来讲,超越3/6的Content
Provider都通过Android的文书存款和储蓄系统或SQLite
数据库建立和睦的数码存款和储蓄系统。

提供程序访问的替代方式

提供程序访问的二种替代格局在运用开发的经过中11分第①:

  • 批量访问:能够经过ContentProviderOperation类中的方法创造一批访问调用,然后通过ContentResolver.applyBatch()执行它们。
  • 异步查询:相应在单独线程中实践查询。
  • 通过Intent访问数据:即便不可能直接向提供程序发送Intent,可是足以向提供程序的运用发送Intent,后者日常具有修改提供程序数据的特级配置。

好的,ContentProvider就介绍那一个吗!!欢迎关注作者的微信公众号!

本身的微信公众号.jpg

系统Uri示例:

  • content://media/internal/images:再次回到设备上囤积的兼具图片
  • content://contacts/people:重临设备上全体联系人音信
  • content://contacts/people/45:再次来到联系人音信中ID为45的联系人记录

Context提供了getContentResolver函数获取ContentResolver对象,之后方可调用它的章程,那个艺术都会转由Uri对应的ContentProvider的同名函数执行

  • insert(Uri,ContentValues):向Uri对应的ContentProvider中插入ContentValues数据
  • delete(Uri,String,String[]):删除Uri对应的ContentProvider中与规则同盟的数码
  • update(Uri,ContentValues,String,String[]):更新与规则相当的多寡
  • query(Uri,String[],String,String[],String):查询与原则极度的数目

UriMatcher工具类:

  • void addUri(String,String,int
    code):该模式用于向UriMatcher对应注册Uri,code代表Uri对应的标识码
  • int match(Uri
    uri):重临Uri的标识码,找不到重回-1

ContentUris工具类,常用语生成查询的Uri

  • withAppendedId(uri,id):用于给路径加上ID部分
  • parseId(Uri):用于从钦赐Uri中剖析出所蕴含的ID值

系统一般会把ContentProvider的Uri,数据列等音信以常量方式公开出来,方便访问

操作系统的ContentProvider

Contacts(管理挂钩人的应用程序)的ContentProvider提供的多少个Uri:

  • ContactsContract.Contacts.CONTENT_U奥迪Q5I:管理关系人的Uri
  • ContactsContract.CommonDataKinds.Phone.CONTENT_UCRUISERI:管理联系人电话的Uri
  • ContactsContract.CommonDataKinds.Email.CONTENT_U中华VI:管理关系人EMail的Uri

Android为多媒体提供的ContentProvider的Uri:

  • MediaStore.Audio.Media.EXTERNAL_CONTENT_UPRADOI:存款和储蓄在表面存款和储蓄器上的音频文件内容的ContentProvider的Uri
  • MediaStore.Audio.Media.INTERNAL_CONTENT_UEnclaveI:存款和储蓄在四哥大里面存款和储蓄器上的音频文件的ContentProvider的Uri
  • MediaStore.Images.Media.EXTERNAL_CONTENT_U大切诺基I:存款和储蓄在外表存款和储蓄器上的图样文件内容的ContentProvider的Uri
  • MediaStore.Images.Media.INTERNAL_CONTENT_UOdysseyI:存储在手机里面存款和储蓄器上的图样内容的ContentProvider的Uri
  • MediaStore.Video.Media.EXTERNAL_CONTENT_URI
  • MediaStore.Video.Media.INTERNAL_CONTENT_UR

ContentObserver类:监听ContentProvider数据变动的监听器须要持续ContentObserver类,同样器重写
该基类所定义的onChange方法,当监听的ContentProvider的数额发生转移时,该onChange将会被触发注册监听器要利用ContentResolver的registerContentObserver函数