首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Android操作系统是否有一个所有应用共享的“`ContentResolver`”对象,还是每个应用程序都有自己的“`ContentResolver`”实例?

Android操作系统是否有一个所有应用共享的“`ContentResolver`”对象,还是每个应用程序都有自己的“`ContentResolver`”实例?
EN

Stack Overflow用户
提问于 2018-03-29 04:09:01
回答 1查看 1.3K关注 0票数 3

我正在接受一门关于Udacity的Android课程,并在题目中遇到了一个同学提出的问题。

Youtube链接到课程

引用视频中的话:

代码语言:javascript
复制
ContentResolver resolver = getContentResolver();
Cursor cursor = resolver.query(DroidTermsExampleContract.CONTENT_URI, null, null, null, null);

此代码访问正确的内容提供程序并从中获取一些数据。我们这里有一些新的词汇概念,所以我要把它分解。第一个新概念是ContentResolver。所以我们的原始图表相当简单。让我们看一下我们以前看到的这幅画。

这幅图的更精确的版本是这样的。

这张图包含一个内容解析器。那么,让这个类坐在应用程序和直接访问内容提供者之间的目的是什么呢? 如果您仔细想想,您的手机上有多个内容提供商,当您下载使用内容提供商存储本地数据的应用程序时,会添加更多的内容提供商。除了DroidTermsExample内容提供程序之外,您还有一个用于联系人的内容提供程序,您的设备有一个用于设备的用户文件的内容提供程序,一个用于跟踪用户警报、日历提供程序和其他一些内容的内容提供者。 另外,你的应用并不是唯一运行在设备上的应用程序。还有其他应用程序可能也在并行使用内容提供商。管理内容提供商正在与哪些应用程序对话,并保持所有数据的同步,可能会变成一个巨大的交通堵塞。这就是内容解析器出现的地方。 内容解析器充当每个应用程序和它想要访问的内容提供者之间的中介。它处理进程间的通信,并使一切保持同步和顺利运行。,即使您有五个进程访问两个内容提供程序。 因此,无论您想要使用哪个内容提供者,都需要通过ContentResolver来实现它。好吧,现在你知道这第一行在做什么了,

代码语言:javascript
复制
ContentResolver resolver = getContentResolver();

为我们提供了对系统内容解析器的引用。,这是访问内容提供者的下一步。

视频中的解释(尤其是上面粗体的标记行)让我清楚地认为,安卓操作系统有一个ContentResolver

它的工作是让那些想和一个或多个应用程序的内容提供商对话的应用程序更容易。

然而,其他学习者似乎有相反的理解。提出的一些论点如下:

来自雄激素设计模式

Content是应用程序中唯一的全局实例,它提供对(和其他应用程序的)内容提供程序的访问。

来自Android文档

当您想要访问内容提供程序中的数据时,可以使用应用程序上下文中的ContentResolver对象作为客户端与提供程序进行通信。

索赔:

由于应用程序的上下文中提到了ContentResolver对象,因此每个应用程序都有自己的内容解析器

我仍然有一个简单的公平理解,即操作系统提供一个ContentResolver,然后将这个解析器带到给定应用程序的上下文中来使用它。这不可能吗?

这是我的第一个Android课程,我在这里是一个绝对的初学者。如果我对这个概念有错误的理解,谁能澄清一下吗?

EN

回答 1

Stack Overflow用户

发布于 2018-03-29 04:50:29

在任何给定的应用程序中,只有一个类的ContentResolver类实例。

查看安卓源代码中实际ContextImpl类(实际实现Context接口的类)的源代码,您将发现抽象ContentResolver类的内部静态ApplicationContentResolver子类,它管理应用程序和系统服务器之间的所有通信。ApplicationContentResolver的一个实例是在ContextImpl的构造函数中创建的,并且对于该上下文(或应用程序)是唯一的。

ApplicationContentResolver将调用委托给ActivityThread类,该类负责管理应用程序的主线程,并向系统服务器提供IPC通信(通过绑定)。在ActivityThread类中,您将发现类似于ActivityThread#acquireProvider()的调用,这些调用要么重新使用现有的提供程序(并增加它的引用计数),要么要求ActivityManagerNative通过系统服务器获取提供者的新实例。这是一个重要的步骤,因为此时系统服务器将检查调用应用程序是否具有所需的权限。

一旦系统服务器确定调用的应用程序有足够的权限来使用ContentProvider,那么它就会创建一个ContentProvider,或者在它存在的情况下重新使用它,并返回对该调用应用程序的引用。

ContentProvider上的文档来看,

数据访问方法可以同时从多个线程调用,并且必须是线程安全的。其他方法(如onCreate())只从应用程序主线程调用,必须避免执行冗长的操作。

这意味着单个ContentProvider实例在多个应用程序之间共享,它的生命周期由系统管理(就像其他组件一样)。

因此,为了总结这一点,每个应用程序都有一个单个ContentResolver实例,整个系统也有一个单个ContentProvider实例(对于给定的权限)。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49547887

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档