在Android系统中,Content Provider作为应用程序四大组件之一,它起到在应用程序之间共享数据的作用,同时,它还是标准的数据访问接口。前面的一系列文章已经分析过Android应用程序的其它三大组件(Activity、Service和Broadcast Receiver)了,本文将简要介绍Content Provider组件在Android应用程序设计中的地位,为进一步学习打好基础。
我们知道,在Android系统上,每一个应用程序都有一个独立的用户ID。为什么要给每一个应用程序分配一个独立的用户ID呢?这是为了保护各个应用程序的数据不被其它应用程序恶意破坏而设计的。Android系统是基于Linux内核来开发的,而在Linux系统中,每一个文件除了文件本身的数据之外,还具有一定的属性,其中最重要的就是文件权限了。所谓的文件权限,就是指对文件的读、写和执行权限。此外,Linux还是一个多用户的操作系统,因此,Linux将系统中的每一个文件都与一个用户以及用户组关联起来,基于不同的用户而赋予不同的文件权限。只有当一个用户对某个文件拥有相应的权限时,才能执行相应的操作,例如,只有当一个用户对某个文件拥有读权限时,这个用户才可以调用read系统调用来读取这个文件的内容。Android系统继承了Linux系统管理文件的方法,为每一个应用程序分配一个独立的用户ID和用户组ID,而由这个应用程序创建出来的数据文件就赋予相应的用户以及用户组读写的权限,其余用户则无权对该文件进行读写。
如果我们通过adb shell命令连上模拟器,切换到/data/data目录下,就可以看到很多以应用程序包(package)命名的文件夹,这些文件夹里面存放的就是各个应用程序的数据文件,例如,如果我们进入到Android系统日历应用程序数据目录com.android.providers.calendar下的databases文件中,会看到一个用来保存日历数据的数据库文件calendar.db,它的权限设置如下所示:
- root@android:/data/data/com.android.providers.calendar/databases # ls -l
- -rw-rw---- app_17 app_17 33792 2011-11-07 15:50 calendar.db
root@android:/data/data/com.android.providers.calendar/databases # ls -l
-rw-rw---- app_17 app_17 33792 2011-11-07 15:50 calendar.db
在前面的十字符-rw-rw----中,最前面的符号-表示这是一个普通文件,接下来的三个字符rw-表示这个文件的所有者对这个文件可读可写不可执行,再接下来的三个字符rw-表示这个文件的所有者所在的用户组的用户对这个文件可读可写不可执行,而最后的三个字符---表示其它的用户对这个文件不可读写也不可执行,因为这是一个数据文件,所认所有用户都不可以执行它是正确的。在接下来的两个app_17字符串表示这个文件的所有者和这个所有者所在的用户组的名称均为app_17,这是应用程序在安装的时候系统分配的,在不同的系统上,这个字符串可能是不一样,不过它所表示的意义是一样的。这意味着只有用户ID为app_17或者用户组ID为app_17的那些进程才可以对这个calendar.db文件进行读写操作。我们通过执行终端上执行ps命令来查看一下哪个进程的用户ID为app_17:
- root@android:/ # ps
- USER PID PPID VSIZE RSS WCHAN PC NAME
- root 1 0 272 184 c009f230 0000875c S /init
- ... ... ... ... ... ... ... ...
- app_17 295 35 107468 21492 ffffffff afd0c38c S com.android.providers.calendar
- .. ... ... ... ... ... ... ...
- root 556 527 892 332 00000000 afd0b24c R ps
root@android:/ # ps
USER PID PPID VSIZE RSS WCHAN PC NAME
root 1 0 272 184 c009f230 0000875c S /init
... ... ... ... ... ... ... ...
app_17 295 35 107468 21492 ffffffff afd0c38c S com.android.providers.calendar
.. ... ... ... ... ... ... ...
root 556 527 892 332 00000000 afd0b24c R ps
这里我们看到,正是这个日历应用程序com.android.providers.calendar进程的用户ID为app_17。这样,就验证了我们前面的分析了:只有这个日历应用程序com.android.providers.calendar才可以对这个calendar.db文件进行读写操作。这个日历应用程序com.android.providers.calendar其实是由一个Content Provider组件来实现的,在下一篇文章中,我们将实现一个自己的Content Provider,然后再对Content Provider的实现原理进行详细分析。
Android系统对应用程序的数据文件作如此严格的保护会不会有点过头了呢?如果一个应用程序想要读写另外一个应用程序的数据文件时,应该怎么办呢?举一个典型的应用场景,我们在开发自己的应用程序时,有时候会希望读取通讯录里面某个联系人的手机号码或者电子邮件,以便可以对这个联系人打电话或者发送电子邮件,这时候就需要读取通讯录里面的联系人数据文件了。
现在在互联网里面,都流行平台的概念,各大公司都打着开放平台的口号,来吸引第三方来为自己的平台做应用,例如,国外最流行的Fackbook开放平台和Google+开放平台等,国内的有腾讯的Q+开放平台,还有新浪微博开放平台、360的开放平台等。这些开放平台的核心就是要开放用户数据给第三方来使使用,就像前面我们说的Android系统的通讯录,它需要把自己联系人数据开放出来给其它应用程序使用。但是,这些数据都是各个平台自己的核心数据和核心竞争力,它们需要有保护地进行开放。Android系统中的Content Provider应用程序组件正是结合上面分析的这种文件权限机制来秉承这种有保护地开放自己的数据给其它应用程序使用的理念。
从另外一个观点来看,即使我们不是在做平台,而只是在做一个应用程序软件,是不是就不需要这么使用到Content Provider机制了呢?非也,现在的应用程序软件,越着公司业务的成长,越来越庞大,越来越复杂。软件工程告诉我们,我们在设计这种大型的复杂的软件的时候,需要分模块和分层次来实现各个子功能组件,使得各个模块功能以松耦合的方式组织在一起完成整个应用程序功能。这样做的好处当然就是便于我们维护和扩展应用程序的代码和功能了,以及适应复杂的业务环境。在一个大型的应用程序软件架构中,从垂直的方向来看,一般都会划分为数据层、数据访问接口层以及上面的业务层。数据层用来保存数据,这些数据可以用文件的方式来组织,也可以用数据库的方式来组织,甚至可以保存在网络中;数据访问层负责向上面的业务层提供数据,而向下管理好数据层的数据;最后业务层通过数据访问层来获取一些业务相关的数据来实现自己的业务逻辑。
基于这种开放平台建设或者复杂软件架构的理念,我们得出一个Android应用程序设计的一般方法,如下图所示:

在这个架构中, 数据层采用数据库、文件或者网络来保存数据,数据访问层使用Content Provider来实现,而业务层就通过一些APP来实现。为了降低各个功能模块间耦合性,我们可以把业务层的各个APP和数据访问层中的Content Provider,放在不同的应用程序进程中来实现,而数据库中的数据统一由Content Provider来管理,即Content Provider拥有对这些文件直接进行读写的权限,同时,它又根据需要来有保护地把这些数据开放出来给上层的APP来使用。
那么,Content Provider又是如何把数据开放给上面的APP使用呢?一方面是这些APP没有权限读取这些数据文件,另一外面是Content Provider和这些APP是在不同的进程空间里面。回忆一下,我们在前面Android进程间通信(IPC)机制Binder简要介绍和学习计划这一系文章中学习的Android系统中Binder进程间通信机制,不同的应用程序之间可以通过Binder进程间调用来传输数据。因此,前面关于一个应用程序应该如何来读写另外一个应用程序的数据的问题的答案就是使用Binder进程间通信机制,虽然一个应用程序不能直接读取另一个应用程序的数据,但是它却可以通过进程间通信方式来请求另一个这个应用程序给它传输数据。这样我们就解决了文件权限限制所带来的问题了。
然而,事情还不是那么简单,一般Content Provider管理的都是大量的数据,如果在进程间传输大量的数据,效率是不是会很低下呢?这时候,前面我们在Android系统匿名共享内存Ashmem(Anonymous Shared Memory)简要介绍和学习计划这一系列文章中学习的匿名共享内存(Anonymous Shared Memory)就派上用场了。把需要在进程间传输的数据都写到共享内存中去,然后只能通过Binder进程间通信机制来传输一个共享内存的打开文件描述符给对方就好了,是不是很简单呢。在Android系统中,Binder进程间通信机制和匿名共享内存机制结合在一起使用,真是太完美了。
Content Provider如何在应用程序之间共享数据以及它在应用程序设计中的地位就简要介绍到这里了。
原博客链接:http://blog.csdn.net/luoshengyang/article/details/6946067

本文节选自《Android系统源代码情景分析》
电子工业出版社出版
罗升阳 著
分享到:
相关推荐
在Android开发中,Content Provider是四大组件之一,它扮演着数据共享的角色,使得不同应用程序间可以安全地访问和操作数据。这篇博文的示例程序"android content provider示例程序(简单记账)"旨在帮助开发者理解...
在Android开发中,Content Provider是四大组件之一,它扮演着数据共享的角色,使得不同应用程序间可以安全地访问和操作数据。本"Android Content Provider Demo"着重于演示如何创建和使用Content Provider来实现跨...
- **Content Provider**:用于存储和检索数据,并将这些数据暴露给其他应用程序使用。 #### 四、Android用户界面设计 ##### 1. 使用XML布局文件 - XML布局文件定义了应用的用户界面结构。 - 常见的布局类型包括...
Content Provider是Android四大组件之一,它扮演着数据管理者的角色,允许不同的应用程序之间共享数据。通过Content Provider,一个应用可以将自己的数据暴露给其他应用,同时也可以访问其他应用公开的数据。这一...
在Android系统中,Content Provider是四大组件之一,它扮演着数据共享的角色,使得不同应用程序之间可以安全地访问和操作数据。这篇博客“简单实现自己的Content Provider(一)”旨在引导开发者如何从零开始构建一...
在Android开发中,Content Provider是四大组件之一,它充当了数据共享和交换的桥梁,使得不同的应用程序之间可以安全地共享数据。本示例将详细解析如何自定义Content Provider,以便在Android应用间实现数据共享。 ...
Content Provider使得应用程序能够将自己的数据结构公开给其他应用,同时也允许访问其他应用的数据。这篇博客将深入探讨Content Provider的工作原理、实现方式以及如何在实际项目中应用。 首先,我们来了解Content ...
Android应用程序由多个组件构成,包括Activity、Service、Broadcast Receiver和Content Provider等。这些组件共同协作来完成特定的任务。 **5.2 应用程序包含的各个文件** 应用程序中的每个组件都需要对应的XML...
- **Content Provider**:用于存储和检索数据,并将这些数据暴露给其他应用程序访问。 - **HelloActivity**示例: - `HelloActivity.java`中定义了一个名为`HelloActivity`的类,该类继承自`Activity`。在`...
总的来说,NotePad小应用程序涵盖了Android开发的基本元素,从用户界面设计、数据存储到应用生命周期管理,为开发者提供了一个实践和学习Android开发的实用平台。通过深入研究和修改NotePad源码,开发者可以进一步...
在Android开发中,Content Provider和SQLite数据库是两个非常重要的组件,它们主要用于数据的存储和共享。下面将详细讲解这两个概念及其用法。 首先,我们来理解Content Provider。Content Provider是Android系统...
Android四大组件详解 Android 应用程序由一些零散的有联系的组件组成,通过一个工程 manifest 绑定在一起。...通过学习 Android 四大组件,你可以更好地掌握 Android 应用程序的开发,提高自己的开发效率和质量。
6. **ch11** - 可能深入到更高级的主题,比如服务(Service)、Broadcast Receiver、Content Provider,或者关于多线程和网络编程的知识。 7. **simplelayouts** - 这个文件夹名字暗示了它包含了一些基础布局的示例...
在Android应用程序开发中,了解并掌握整个流程是至关重要的,特别是对于那些志在从事IT行业的“事业编”人员。以下是一些关键知识点的详细说明: 1. **Java基础知识**: - Java是一种面向对象的编程语言,其核心...
6. **Android核心模块**:深入研究四大组件(Activity、Broadcast Intent Receiver、Service、Content Provider)和Android应用程序框架,理解它们在应用程序中的角色和交互方式。 - **Activity Manager**:管理...
Android 应用程序组件是 Android 平台上的一个基本概念,包括 Activity、Service、Broadcast Receiver、Content Provider 等组件。这些组件可以单独使用,也可以组合使用以实现更加复杂的功能。 4. 基于 Android 的...
在Android系统中,Content Provider是一种核心组件,它负责在应用程序之间共享数据。"自定义Provider demo"是一个关于如何在Android中创建并使用自定义Content Provider的实例教程。这个教程特别适用于那些想要学习...
通过本教程的学习,读者不仅可以掌握如何使用Eclipse开发Android应用程序的基础知识,还能深入了解Android平台的关键概念和技术细节。无论您是否有移动开发经验,都能够顺利上手并逐步提高自己的开发能力。未来,...
### Android应用程序开发...通过以上知识点的学习,开发者可以从零开始掌握Android应用程序的开发方法,并能够独立完成从简单到复杂的应用程序设计与实现。这对于想要进入移动互联网领域的开发者来说是非常宝贵的经验。