Android OS是否有一个由所有应用程序共享的“ContentResolver”对象,或者每个应用程序都有自己的“ContentResolver”实例?

时间:2018-03-29 04:09:02

标签: java android android-contentprovider android-contentresolver

我正在接受关于Udacity的Android课程,并且在同一个学习者的标题中遇到了问题。

Youtube link to lesson

引自视频:

ContentResolver resolver = getContentResolver();
Cursor cursor = resolver.query(DroidTermsExampleContract.CONTENT_URI, null, null, null, null);
  

此代码访问正确的内容提供程序并获取一些数据   从中。我们在这里有一些新的词汇概念,所以我要去了   打破它。第一个新概念是ContentResolver。所以我们的   原始图表相当简单。让我们来看看这张图   我们之前见过。

Simple

  

此图纸的更准确版本就是这个。

More Accurate

  

和   此图纸涉及内容解析器。那么目的是什么呢?   让这个课程坐在你的应用程序和直接访问   内容提供商?

     

如果您考虑一下,会有多个内容   您手机上的提供商,以及您添加更多内容提供商   下载存储使用内容提供商的本地数据的应用程序。   除了DroidTermsExample内容提供商,您还有一个内容   联系人提供商,您的设备有一个用户的文件   设备,跟踪用户警报的设备,日历提供商,   和其他一些人。

     

此外,您的应用并不是唯一运行的应用   设备。还有其他应用也可能正在使用内容   供应商并行。管理正在与之交谈的内容提供商   什么应用程序,并保持所有数据同步,可能会变成一个巨大的   交通阻塞。这就是内容解析器的用武之地。

     

内容解析器充当每个应用和广告之间的媒介   它想要访问的内容提供者或提供者。它处理   进程间通信并使所有内容保持同步和运行   顺利。即使您有五个进程访问两个内容   提供者。

     

因此,您需要使用内容提供商的任何地方   通过ContentResolver完成。好的,现在你知道这是什么了   第一行正在做,

ContentResolver resolver = getContentResolver();
  

让我们参考系统的内容   解析器。这是访问内容提供商的下一步。

视频中的解释(特别是上面标有粗体标记的行)显然让我觉得Android操作系统只有一个ContentResolver

它的工作是让所有想要与一个或多个应用程序的内容提供商交谈的应用程序的生活更轻松。

<小时/> 然而,其他学习者似乎有相反的理解。给出的一些论点是:

来自androiddesignpatterns

  

内容解析器是您的单一全局实例   提供对您(和其他应用程序)的访问的应用程序   内容提供商。

来自Android docs

  

如果要访问内容提供商中的数据,请使用   ContentResolver对象在应用程序的Context中进行通信   与提供者作为客户。

索赔:

  

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

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

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

1 个答案:

答案 0 :(得分:1)

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

在Android的源代码中查看实际ContextImpl类(实际实现Context接口的类)的源代码,您将找到abstract {{的内部静态ApplicationContentResolver子类。 3}}管理应用程序和系统服务器之间所有通信的类。 ApplicationContentResolver的实例是在ContextImpl的构造函数内创建的,对于该上下文(或应用程序)是唯一的。

ApplicationContentResolver委托它调用ContentResolver类,该类负责管理应用程序的主线程,并提供IPC通信(通过活页夹)到系统服务器。在ActivityThread课程中,您会发现ActivityThread之类的调用要么重新使用现有的提供者(并增加其引用次数),要么要求 ActivityThread#acquireProvider()来获取通过系统服务器提供的新实例。这是一个重要的步骤,因为此时系统服务器将检查调用应用程序是否具有所需的权限。

系统服务器确定调用应用程序有足够权限使用ContentProvider后,创建 a ContentProvider重新使用 on是否存在,并将对该引用返回给调用应用程序。

来自ContentProvider的文档,

  

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

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

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