问题描述
关于 Android 内容提供者的文档 描述了使用 ContentResolver
,从 getContentResolver()
获取,用于访问内容.
The documentation on Android content providers describes using a ContentResolver
, obtained from getContentResolver()
, to access the content.
然而,还有一个 ContentProviderClient
,可以从 getContentResolver().acquireContentProviderClient(authority)
获得.它似乎提供了或多或少与 ContentResolver
中可用的方法相同的方法,用于访问来自提供者的内容.
However there is also a ContentProviderClient
, which can be obtained from getContentResolver().acquireContentProviderClient(authority)
. It seems to provide more or less the same methods available in the ContentResolver
for accessing content from the provider.
我什么时候应该使用 ContentProviderClient
而不是直接使用 ContentResolver
?有什么好处?
When should I use a ContentProviderClient
instead of just using the ContentResolver
directly? What are the benefits?
推荐答案
您的 android 设备有许多数据库,每个数据库都由唯一的内容权限标识.这是 content://uri 中的域名"等效部分——第一个斜杠之前的所有内容.
Your android device has many databases, each of which is identified by a unique Content Authority. This is the "domain name" equivalent part in the content:// uri -- everything before the first slash.
ContentResolver
存储提供从 String contentAuthority
到 ContentProvider
的映射的数据.当你调用 ContentResolver.query()
或 update()
或你有什么时,URI 被解析成它的组件,确定 contentAuthority 字符串,并且 contentResolver 必须在该映射中搜索匹配的字符串,并将查询定向到正确的提供者.这种昂贵的搜索在每次调用期间都会发生,因为 URI 可能因调用而异,并且具有不同的 contentAuthority.此外,建立和断开与该特定提供者的连接可能会涉及一些成本——它不能在调用之间重复使用.我不确定那里涉及的开销,这是一些非常深的操作系统级代码.
ContentResolver
stores data providing a mapping from String contentAuthority
to ContentProvider
. When you call ContentResolver.query()
or update()
or what have you, the URI is parsed apart into its components, the contentAuthority string is identified, and contentResolver has to search that map for a matching string, and direct the query to the right provider. This expensive search occurs during every single call, because the URI might be different from call to call, with a different contentAuthority as well. Additionally, there may be some costs involved in setting up and tearing down a connection to that specific provider -- It can't be reused across calls. I'm not sure of the overhead involved there, that's some pretty deep OS level code.
相比之下,当您调用 acquireContentProviderClient(authority)
时,我需要什么提供者?"查找完成一次,您将获得一个 ContentProviderClient
,它本质上是到 ContentProvider
的直接链接.(您和提供者之间存在一些涉及跨线程通信和并发锁定的胶水).但是,当您使用 ContentProviderClient
时,您将直接与提供者对话以获得您请求的权限.这消除了不断重新计算我想要哪个供应商?"的浪费.
By contrast, when you call acquireContentProviderClient(authority)
, that "what-provider do I need?" lookup is done once, and you are given a ContentProviderClient
which is essentially a direct link to the ContentProvider
. (There's a bit of glue between you and the provider that involves cross-thread communication and concurrency locking). However, when you use ContentProviderClient
, you will talk directly to the Provider for the authority you requested. This removes the waste of constantly re-computing "which provider do I want?"
注意:根据 acquireContentProviderClient() 文档:如果您获得 ContentProviderClient,调用方必须通过调用 ContentProviderClient.release() 这将允许系统释放它确定没有其他原因使其保持活动状态的提供者."所以本质上,让一个陈旧的客户端打开将迫使提供者在后台继续作为服务运行.所以,记得清理!
NOTE: Per acquireContentProviderClient() documentation: If you obtain a ContentProviderClient, "The caller must indicate that they are done with the provider by calling ContentProviderClient.release() which will allow the system to release the provider it it determines that there is no other reason for keeping it active." So essentially, leaving a stale Client open will force the Provider to keep running as a service in the background. So, remember to clean up!
总结:
多次调用不同的 contentAuthorities: 使用 ContentResolver
.
重复调用同一权限: 获取并使用 ContentProviderClient
.完成后记得释放()它.
Repeated calls to the same Authority: Obtain and use ContentProviderClient
. Remember to release() it when you're done.
这篇关于使用 ContentProviderClient 与 ContentResolver 访问内容提供者的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!