ContentProvider的功能和意义:

主要用于对外共享数据,也就是通过ContentProvider把应用中的数据共享给其他应用访问,其他应用可以通过ContentProvider对指定应用中的数据进行操作。

实现在不同应用程序之间共享数据,在应用程序之间交换数据,一个应用程序A把自己的数据通过ContentProvider暴露给其他程序使用B,B就可以通过ContentResolver来操作ContentProvider暴露的数据,包括增,删,查,改

1、ContentProvider使用表的形式来组织数据
   无论数据的来源是什么,ContentProvider都会认为是一种表,然后把数据组织成表格
2、ContentProvider提供的方法
public boolean onCreate() 在创建ContentProvider时调用
public Cursor query(Uri, String[], String, String[], String) 用于查询指定Uri的ContentProvider,返回一个Cursor
public Uri insert(Uri, ContentValues) 用于添加数据到指定Uri的ContentProvider中
public int update(Uri, ContentValues, String, String[]) 用于更新指定Uri的ContentProvider中的数据
public int delete(Uri, String, String[]) 用于从指定Uri的ContentProvider中删除数据
public String getType(Uri) 用于返回指定的Uri中的数据的MIME类型
*如果操作的数据属于集合类型,那么MIME类型字符串应该以vnd.android.cursor.dir/开头。
例如:要得到所有person记录的Uri为content://contacts/person,那么返回的MIME类型字符串为"vnd.android.cursor.dir/person"。
*如果要操作的数据属于非集合类型数据,那么MIME类型字符串应该以vnd.android.cursor.item/开头。
例如:要得到id为10的person记录的Uri为content://contacts/person/10,那么返回的MIME类型字符串应为"vnd.android.cursor.item/person"。
3、每个ContentProvider都有一个公共的URI,这个URI用于表示这个ContentProvider所提供的数据。Android所提供的ContentProvider都存放在android.provider包当中

二,Uri类简介

1,为系统的每一个资源给其一个名字,比方说通话记录。每个ContentProvider都有一个公共的URI,这个URI用于表示这个ContentProvider所提供的数据。

例Uri:content://com.hust.uri/words

Uri指定了将要操作的ContentProvider,其实可以把一个Uri看作是一个网址,我们把Uri分为三部分。
第一部分是"content://"。可以看作是网址中的"http://"。
第二部分是主机名或authority,用于唯一标识这个ContentProvider,外部应用需要根据这个标识来找到它。可以看作是网址中的主机名,比如"blog.csdn.net"。
第三部分是路径名,资源部分,用来表示将要操作的数据。

例:content://com.hust.uri/words

访问的资源是words/2,意味着访问word数据表中的全部数据

例:content://com.hust.uri/words/2

访问的资源是words/2,意味着访问word数据中ID为2的记录

例:content://com.hust.uri/words/2/word

访问的资源是words/2,意味着访问word数据中ID为2的记录的word字段

把一个字符串转换成Uri,是Uri类的静态方法:

Uri uri = Uri.parse("content://com.hust.uri/contact")

2,UriMatcher类使用介绍

因为Uri代表了要操作的数据,所以我们经常需要解析Uri,并从Uri中获取数据。Android系统提供了两个用于操作Uri的工具类,分别为UriMatcher和ContentUris

UriMatcher类用于匹配Uri:

A,void addURI(String authority,String path,int code)向UriMatcher中注册Uri,authority和path组成一个Uri,code代表该Uri对应的标识码

B,int match(Uri uri);根据前面注册的Uri来判断指定的Uri对应的标识码

UriMatcher matcher=new UriMatcher(UriMatcher.NO_MATCH);
matcher.addURI("com.hust.uri","words",1);
matcher.addURI("com.hust.uri","words/#",2); 

com.hust.uri/words/#表示words下的所有数据uri的表示为2

匹配结果如下:

matcher.match(Uri.parse("content://com.hust.uri/words"));
//返回标识码1
matcher.match(Uri.parse("content://com.hust.uri/words/2"));
//返回标识码2
matcher.match(Uri.parse("content://com.hust.uri/words/10"));
//返回标识码2

注册完需要匹配的Uri后,就可以使用sMatcher.match(uri)方法对输入的Uri进行匹配,如果匹配就返回匹配码,匹配码是调用addURI()方法传入的第三个参数

3,ContentUris类使用介绍

ontentUris类用于操作Uri路径后面的ID部分,它有两个比较实用的方法:
withAppendedId(uri, id)用于为路径加上ID部分:

Uri resultUri = ContentUris.withAppendedId(uri, 10);
//生成后的Uri为:content://com.hust.personprovider/person/10

parseId(uri)方法用于从路径中获取ID部分:

Uri uri = Uri.parse("content://com.hust.uri.personprovider/person/10")
long personid = ContentUris.parseId(uri);//获取的结果为:10

三,开发ContentProvider

1,开发一个ContentProvider子类,继承ContentProvider,实现query,insert,update,delete等方法

2,在Manifest.xml清单文件中注册该ContentProvider,指定其Android:authorities属性

public class FirstProvider extends ContentProvider
{// 第一次创建该ContentProvider时调用该方法@Overridepublic boolean onCreate(){System.out.println("===onCreate方法被调用===");return true;}// 该方法的返回值代表了该ContentProvider所提供数据的MIME类型@Overridepublic String getType(Uri uri){System.out.println("~~getType方法被调用~~");return null;}// 实现查询方法,该方法应该返回查询得到的Cursor@Overridepublic Cursor query(Uri uri, String[] projection, String where,String[] whereArgs, String sortOrder){System.out.println(uri + "===query方法被调用===");System.out.println("where参数为:" + where);return null;}// 实现插入的方法,该方法应该新插入的记录的Uri@Overridepublic Uri insert(Uri uri, ContentValues values){System.out.println(uri + "===insert方法被调用===");System.out.println("values参数为:" + values);return null;}// 实现删除方法,该方法应该返回被删除的记录条数@Overridepublic int delete(Uri uri, String where, String[] whereArgs){System.out.println(uri + "===delete方法被调用===");System.out.println("where参数为:" + where);return 0;}// 实现删除方法,该方法应该返回被更新的记录条数@Overridepublic int update(Uri uri, ContentValues values, String where,String[] whereArgs){System.out.println(uri + "===update方法被调用===");System.out.println("where参数为:"+ where + ",values参数为:" + values);return 0;}
}

这4个方法用于供其他应用通过ContentProvider调用。
注册ContentProvider:

<!-- 注册一个ContentProvider --><providerandroid:exported="true"android:name=".FirstProvider"android:authorities="org.providers.firstprovider"></provider>

android:authorities属性是一定要配置的,指定该ContentProvider对应的Uri

上面配置指定了该ContentProvider被绑定到“content://org.providers.firstprovider”,这意味着其他应用的ContentResovler向该Uri执行query,insert,update,delete方法时,实际上是调用该ContentProvider的query,insert,update,delete方法,ContentResovler调用方法时将参数传给ContentProvider对应的方法参数。

四,开发contentResovler

通过getContentResolver()方法获取ContentResolver对象,获取ContentResolver对象之后,接下来可调用query,insert,update,delete方法了,实际上调用的是指定Uri对应的ContentProvider的query,insert,update,delete方法

例:界面4个按钮,分别对应增删查改功能:

public class FirstResolver extends Activity
{ContentResolver contentResolver;//声明变量Uri uri = Uri.parse("content://org.providers.firstprovider/");//FirstProvider的Uri@Overridepublic void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main);// 获取系统的ContentResolver对象contentResolver = getContentResolver();}public void query(View source){// 调用ContentResolver的query()方法。// 实际返回的是该Uri对应的ContentProvider的query()的返回值Cursor c = contentResolver.query(uri, null, "query_where", null, null);Toast.makeText(this, "远程ContentProvide返回的Cursor为:" + c,Toast.LENGTH_LONG).show();}public void insert(View source){ContentValues values = new ContentValues();values.put("name", "fkjava");// 调用ContentResolver的insert()方法。// 实际返回的是该Uri对应的ContentProvider的insert()的返回值Uri newUri = contentResolver.insert(uri, values);Toast.makeText(this, "远程ContentProvide新插入记录的Uri为:"+ newUri, Toast.LENGTH_LONG).show();}public void update(View source){ContentValues values = new ContentValues();values.put("name", "fkjava");// 调用ContentResolver的update()方法。// 实际返回的是该Uri对应的ContentProvider的update()的返回值int count = contentResolver.update(uri, values, "update_where", null);Toast.makeText(this, "远程ContentProvide更新记录数为:"+ count, Toast.LENGTH_LONG).show();}public void delete(View source){// 调用ContentResolver的delete()方法。// 实际返回的是该Uri对应的ContentProvider的delete()的返回值int count = contentResolver.delete(uri, "delete_where", null);Toast.makeText(this, "远程ContentProvide删除记录数为:"+ count, Toast.LENGTH_LONG).show();}

五,ContentProvider与ContentResolver的关系

ContentResolver对指定的Uri指定CRUD等数据操作,但是Uri并不是真正的数据中心,因此这些CRUD操作会委托给Uri对应的ContentProvider来实现。通常来说,A应用通过ContentResolver执行CRUD操作,这些操作都需要指定Uri参数,Android系统就根据该Uri找到对应的ContentProvider(该ContentProvider通常属于B应用),ContentProvider则负责实现CRUD方法,完成对底层数据的增删改查等操作,这样A应用就可以访问,修改B应用的数据了

Android中ContentProvider组件数据共享相关推荐

  1. 【Android】Android中ContentProvider组件详解

    原文来自:http://blog.csdn.net/zuolongsnail/article/details/6566317 ContentProvider(内容提供者)是Android中的四大组件之 ...

  2. Android中ContentProvider组件详解

    一.Android四大组件 Android四大组件是Activity, Service, Content Provider,Broadcast Receiver. Activity作为程序界面,直接与 ...

  3. Android中四大组件

    Android四大组件: 一.分类:Activity.Service.Broadcast Receiver.Content Provider. 1.Activity   (1)一个Activity通常 ...

  4. Android 中ContentProvider和Uri详解

    一.使用ContentProvider(内容提供者)共享数据 ContentProvider在android中的作用是对外共享数据,也就是说你可以通过ContentProvider把应用中的数据共享给 ...

  5. android content item,Android中ContentProvider的应用实例

    一.ContentProvider简介 当应用继承ContentProvider类,并重写该类用于提供数据和存储数据的方法,就可以向其他应用共享其数据.虽然使用其他方法也可以对外共享数据,但数据访问方 ...

  6. Android中四大组件(四大天王)

    Activity Activity的生命周期(其他博文中有详细) 注意点:被其他Activity覆盖当前Activity进入OnPasue(), 启动其他Acitivity当前Acitivity进入O ...

  7. Android中设置组件多进程

    MultiProcessComponent 源码地址 github源码下载地址https://github.com/onlynight/MultiProcessComponent 概述 这个demo中 ...

  8. Android中BroadcastReceiver组件详解

    Android系统的4个组件终于还剩一种组件了BroadcastReceiver,这个组件是全局监听器,可以监听系统全局的广播消息,可以方便的实现系统中不同组件之间的通信 BroadcastRecei ...

  9. 进阶篇-用户界面:4.Android中常用组件

    1.下拉菜单 在Web开发中,HTML提供了下拉列表的实现,就是使用<select>元素实现一个下拉列表,在其中每个下拉列表项使用<option>表示即可.这是在Web开发中一 ...

最新文章

  1. 编译安装 redis 2.2.14
  2. java数独最快解_[分享]数独的JAVA解法
  3. postgresql 客户端_Postgresql体系结构
  4. 【玩转cocos2d-x之三十三】游戏嵌入Webview网页
  5. object数据类型
  6. linux oracle 运维_Oracle查询当前的crs/has自启动状态实例教程
  7. asp.net怎么生成json数据_mysql数据库配置文件不知道怎么配置?用这个工具一键生成...
  8. 如何在TypeScript中使用JS类库
  9. matlab pdm转pcm_STM32F407 PDM转PCM问题
  10. 阿里巴巴Java开发文档2020版学习-命名风格
  11. 【Altium Designer2018设计简单的PCB文件实例】
  12. graphpad prism柱状图横坐标斜着_GraphPad Prism绘图教程 | 如何制作对数坐标的图表...
  13. c语言short a=32768,C语言中short整型资料的范围“-32768——32767”中的“-32768”是如何确定的?...
  14. 如何以管理员身份进入dos命令窗口
  15. python代码实现蜡笔小新
  16. My Fifty-eighth - Page - 全排列 - By Nicolas
  17. c语言limits.h的作用,limits.h - C语言标准库
  18. C++中cout<<后面加endl什么意思?
  19. 腾讯云 mysql 数据库名_腾讯云数据库MySQL如何选择配置
  20. win7开机后svchost.exe占用内存的问题解决

热门文章

  1. 蓝牙BLE ATT剖析(二)-- PDU
  2. 十六、广义表的建立与基本操作
  3. java多线程runnable_Java 多线程 之 Runnable
  4. 排序 (5)计数排序“概念”
  5. 跨链(8)Cosmos之“跨链交互协议IBC”前言
  6. IDA无法反编译 and 提示错误
  7. 06-Firmware Configuration Framework
  8. 一次讲清UNICODE
  9. 常用ARM指令总结(未完待续)
  10. 2020-10-29(Android 的DEX ,ODEX,ELF )