java - Android 操作系统是否有一个由所有应用程序共享的 `ContentResolver` 对象,或者每个应用程序是否都有自己的 `ContentResolver` 实例?

标签 java android android-contentprovider android-contentresolver

我正在 Udacity 上学习 Android 类(class),并且遇到了一位学习者在标题中提出的问题。

Youtube link to lesson

引用自视频:

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

This code accesses the correct content provider and grabs some data from it. We've got some new concepts of vocabulary here, so I'm going to break it down. The first new concept is the ContentResolver. So our original diagram is fairly simplistic. Let's look at this drawing that we saw before.

Simple

The more accurate version of this drawing is this.

More Accurate

And this drawing involves a content resolver. So what's the purpose of having this class sit between your app and direct access to the content provider?

If you think about it, there are multiple content providers on your phone, and you add more content providers when you download apps that store local data, which use content providers. Besides the DroidTermsExample content provider, you have a content provider for contacts, your device has one for user files of the device, one that keeps track of user alarms, the calendar provider, and some others.

Also, your app is not the only app running on the device. There are other apps that might also be using content providers in parallel. Managing what content providers are talking to what apps, and keeping all the data in sync, could turn into a huge traffic jam. That's where the content resolver comes in.

The content resolver acts as an intermediary between each app and the content provider, or providers, it wants to access. It handles inter-process communication and keeps everything in sync and running smoothly. Even if you have five processes accessing two content providers.

So wherever you want to use a Content Provider, you'll need to do it through a ContentResolver. Okay, so now you know what this first line is doing,

ContentResolver resolver = getContentResolver();

getting us a reference to the system's Content Resolver. This is the next step for accessing the Content Provider.

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

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


然而,同学们似乎有相反的理解。给出的一些参数是:

来自 androiddesignpatterns :

The Content Resolver is the single, global instance in your application that provides access to your (and other applications’) content providers.

来自Android docs :

When you want to access data in a content provider, you use the ContentResolver object in your application's Context to communicate with the provider as a client.

声明:

Since it is mentioned ContentResolver object in your application's Context, hence each Application has it's own Content Resolver

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

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

最佳答案

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

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

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

一旦系统服务器确定调用应用程序有足够的权限使用 ContentProvider,它就会创建 ContentProvider重新使用如果它存在并返回对调用应用程序的引用。

来自 ContentProvider 的文档,

Data access methods may be called from many threads at once, and must be thread-safe. Other methods (such as onCreate()) are only called from the application main thread, and must avoid performing lengthy operations.

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

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

关于java - Android 操作系统是否有一个由所有应用程序共享的 `ContentResolver` 对象,或者每个应用程序是否都有自己的 `ContentResolver` 实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49547887/

相关文章:

java - 避免传递服务/管理器对象

android检查字符串是否包含0-9以外的字符

android - 如何动态添加edittext到android

android - 致命异常 asyncTask #1 主机可能不为空

java - 需要 ContentProvider 来访问 SharedPreferences

java - 运行 Apache Camel 时出错

java - 设置 JButton 的默认焦点

java - Firebase 查询不显示所有数据

android - 根据电话号码添加原始联系人时联系人重复

java - 当我尝试写入或更新 SQLite 数据库时,我的联系人应用程序停止