(十二)ContentProvider

(1)ContentProvider是什么?

ContentProvider,简称CP。

做App开发的同学,尤其是电商类App,对CP并不熟悉,对这个概念的最大程度的了解,也仅仅是建立在书本上,它是Android四大组件中的一个。

做系统管理类的App,比如说手机助手这种,有机会频繁使用CP。

而对于应用类App,数据通常存在服务器端,其它应用类App也想使用的时候,一般都是从服务器取数据,所以没机会使用到CP。

有时候我们会在自己的App中读取通信录或者短信的数据,这时候就需要用到CP了。通信录或者短信的数据,是以CP的形式提供的,我们在App这边,是使用方。

对于做应用类App的同学,很少有机会自定义CP供其它App使用。

我们快速回顾一下在App中怎么使用CP。

1)定义CP的App1:

在App1中定义一个CP的子类MyContentProvider,并在Manifest中声明,为此要在MyContentProvider中实现CP的增删改查四个方法:

2)使用CP的App2:

在App2访问App1中定义的CP,为此,要使用到ContentResolver,它也提供了增删改查4个方法,用于访问App1中定义的CP:

首先我们看一下ContentResolver的增删改查这4个方法的底层实现,其实都是和AMS通信,最终调用App1的CP的增删改查4个方法,后面我们会讲到这个流程是怎么样的。

其次,URI是CP的身份证,唯一标识。

我们在App1中为CP声明URI,也就是authorities的值为baobao,那么在App2中想使用它,就在ContentResolver的增删改查4个方法中指定URI,格式为:

uri = Uri.parse("content://baobao/");

接下来把两个App都进入debug模式,就可以从App2调试进入App1了,比如说,query操作。

(2)CP的本质

CP的本质是把数据存储在SQLite数据库中。

各种数据源,有各种格式,比如短信、通信录,它们在SQLite中就是不同的数据表,但是对外界的使用者而言,就需要封装成统一的访问方式,比如说对于数据集合而言,必须要提供增删改查四个方法,于是我们在SQLite之上封装了一层,也就是CP。

(3)匿名共享内存(ASM)

CP读取数据使用到了匿名共享内存,英文简称ASM,所以你看上面CP和AMS通信忙的不亦乐乎,其实下面别有一番风景。

关于ASM的概念,它其实也是个Binder通信,我画个图哦,你们就明白了:

什么?还没看懂?那我再画一个类的交互关系图:

这里的CursorWindow就是匿名共享内存。

这个流程,简单来说是这样的:

1)Client内部有一个CursorWindow对象,发送请求的时候,把这个CursorWindow类型的对象传过去,这个对象暂时为空。

2)Server收到请求,搜集数据,填充到这个CursorWindow对象。

3)Client读取内部的这个CursorWindow对象,获取到数据。

由此可见,这个CursorWindow对象,就是匿名共享内存,这是同一块匿名内存。

举个生活中的例子就是,你定牛奶,在你家门口放个箱子,送牛奶的人每天早上往这个箱子放一袋牛奶,你睡醒了去箱子里取牛奶。这个牛奶箱就是匿名共享内存。

(4)CP与AMS的通信流程

接下来我们看一下CP是怎么和AMS通信的。

能坚持看到这里的人,都不容易。我努力多贴图,不贴代码,即使有代码,也是App开发人员能看懂的代码。

还是拿App2想访问App1中定义的CP为例子。我们就看CP的insert方法。

上面这5行代码,包括了启动CP和执行CP方法两部分,分水岭在insert方法,insert方法的实现,前半部分仍然是在启动CP,当CP启动后获取到CP的代理对象,后半部分是通过代理对象,调用insert方法。

整体的流程如下图所示:

1)App2发送消息给AMS,想要访问App1中的CP。

2)AMS检查发现,App1中的CP没启动过,为此新开一个进程,启动App1,然后获取到App1启动的CP,把CP的代理对象返回给App2。

3)App2拿到CP的代理对象,也就是IContentProvider,就调用它的增删改查4个方法了,接下来就是使用ASM来传输数据或者修改数据了,也就是上面提到的CursorWindow这个类,取得数据或者操作结果即可,作为App的开发人员,不需要知道太多底层的详细信息,用不上。

至此,关于CP的介绍就结束了。下一篇文章,我们看一下App的安装流程,也就PMS。

写给Android App开发人员看的Android底层知识(7)的更多相关文章

  1. 写给Android App开发人员看的Android底层知识(1)

    这个系列的文章一共8篇,我酝酿了很多年,参考了很多资源,查看了很多源码,直到今天把它写出来,也是战战兢兢,生怕什么地方写错了,贻笑大方. (一)引言 早在我还是Android菜鸟的时候,有很多技术我都 ...

  2. 写给Android App开发人员看的Android底层知识(2)

    (五)AMS 如果站在四大组件的角度来看,AMS就是Binder中的Server. AMS全称是ActivityManagerService,看字面意思是管理Activity的,但其实四大组件都归它管 ...

  3. 写给Android App开发人员看的Android底层知识(6)

    (十一)BroadcastReceiver BroadcastReceiver,也就是广播,简称Receiver. 很多App开发人员表示,从来没用过Receiver.其实吧,对于音乐播放类App,用 ...

  4. 写给Android App开发人员看的Android底层知识(3)

    (七)App启动流程第2篇 书接上文,App启动一共有七个阶段,上篇文章篇幅所限,我们只看了第一阶段,接下来讲剩余的六个阶段,仍然是拿斗鱼App举例子. 简单回顾一下第一阶段的流程,就是Launche ...

  5. 写给Android App开发人员看的Android底层知识(5)

    (十)Service Service有两套流程,一套是启动流程,另一套是绑定流程.我们做App开发的同学都应该知道. 1)在新进程启动Service 我们先看Service启动过程,假设要启动的Ser ...

  6. 写给Android App开发人员看的Android底层知识(8)

    (十)PMS及App安装过程 PMS,全称PackageManagerService,是用来获取Apk包的信息的. 在前面分析四大组件与AMS通信的时候,我们介绍过,AMS总是会使用PMS加载包的信息 ...

  7. 写给Android App开发人员看的Android底层知识(4)

    (八)App内部的页面跳转 在介绍完App的启动流程后,我们发现,其实就是启动一个App的首页. 接下来我们看App内部页面的跳转. 从ActivityA跳转到ActivityB,其实可以把Activ ...

  8. 一看就懂的Android APP开发入门教程

    一看就懂的Android APP开发入门教程 作者: 字体:[增加 减小] 类型:转载   这篇文章主要介绍了Android APP开发入门教程,从SDK下载.开发环境搭建.代码编写.APP打包等步骤 ...

  9. 谋哥:App开发人员的苦逼不值得怜悯!!

    [谋哥每天一干货,第四十篇]         为什么取这个标题呢?由于昨天一些本来"支持"谋哥的人看到谋哥搞收费VIP群,认为谋哥赚苦逼开发人员的钱非常不道德,且说谋哥我写的东西都 ...

随机推荐

  1. 多云时代,海外微软Azure云与国内阿里云专线打通性能测试

    本文地址:http://www.cnblogs.com/taosha/p/6528730.html 在云计算的大时代,大型客户都有业务全球拓展的需求,考虑到成本,时间因素,一般都是选择云计算,现在云计 ...

  2. Xcode新建python项目

    1.找到电脑上安装Python的路径.OSX系统默认安装了python,默认的路径为/usr/bin/python.不确定的情况下,也可以打开命令行,用 whereis python 命令查看 2.打 ...

  3. 通过VMware安装Linux操作系统

    1.安装好vmvare,下载好Linux,本文采用redhat 6.5  (下载linux可参考http://www.linuxidc.com/Linux/2007-09/7399.htm) 2.选择 ...

  4. MySQL Online DDL的改进与应用

        本文简析Online DDL的实现原理与使用过程注意事项.       任何DDL操作,执行者都需要预先测试或者清晰了解这个操作会给数据库带来的影响是否是在业务期间数据库的可承受范围内,尤其是 ...

  5. 【原】Unity Shader VS UDK Material Editor

    UDK 的材质编辑器十分好用,毕竟是所见即所得的.虽然unity也有类似第三方插件,但易用性还是差很多,下面主要是,把一些常见表达式概念对应起来. 1. UDK CameraVector (相机位向量 ...

  6. Javascript中Array(数组)对象常用的几个方法

    Javascript中Array数组的几个常用方法 pop()  --获取数组中末尾的元素 shift() --获取数组中首位元素 push() --在数组中末尾增加元素 slice()  --按照下 ...

  7. macOS 下配置 MAMP 开发环境(Mac + Apache + Mysql + PHP)

    macOS 中已经内置了 PHP.Python.Ruby.Perl 等常用的脚本语言,以及 Apache HTTP 服务器,所以使用起来非常方便.本文以最新的 macOS Sierra 10.12 配 ...

  8. C# 在iis windows authentication身份验证下,如何实现域用户自动登录

    前言: 该博文产生的背景是有个项目在客户那部署方式为iis windows身份验证,而客户不想每次登录系统都要输入帐号和密码来登录. 因此需要得到域用户,然后进行判断该用户是否可以进入系统. 解决方法 ...

  9. 深入浅出理解yield

    索引 转载部分内容来自:http://www.jianshu.com/p/d09778f4e055 [彻底理解yield] http://blog.csdn.net/haskei/article/de ...

  10. java泛型探索——介绍篇

    1. 泛型出现前后代码对比 先来看看泛型出现前,代码是这么写的: List words = new ArrayList(); words.add("Hello "); words. ...