【问题标题】:Disable notifications on a ContentProvider URI禁用 ContentProvider URI 上的通知
【发布时间】:2013-04-08 06:27:33
【问题描述】:

我正在寻找一种方法来暂停给定ContentProviderUri 上的通知。用例是:

  1. Activity 通过CursorLoader 绑定到CursorAdapter
  2. Service 可能会在 ContentProvider 上执行大量批量、单行更新。
  3. CursorLoader 将在每次更新行时重新加载其内容,因为ContentProvider 通过ContentResolver#notifyChange 通知听众。

由于我无法编辑ContentProvider,并且我无法控制批处理查询的执行,有没有办法暂停Uri(在执行Service)上的通知,直到所有ContentProvider -托管查询已执行?我需要这个是为了避免CursorLoader的不断重新查询引起的闪烁。

【问题讨论】:

  • 为了做到这一点:您对服务和 CP 都没有影响?另一方面,如果服务在您的控制之下,请提供更多详细信息,说明您正在执行哪种 CP 更新。
  • 我正在一个简单的for 循环中执行一系列“更新或插入”类型的查询。我正在使用ContentProvider,它会在每个insertupdate 之后发出通知,但是在这种特殊情况下,我希望能够暂停所有通知,直到我完成所有实体的更新。
  • 更详细地说,我正在使用 Nicolas Klein (github.com/foxykeep/ContentProviderCodeGenerator) 的生成器生成我的ContentProvider,它在update(Uri uri, ContentValues values, String selection, String[] selectionArgs) 的末尾执行一个简单的getContext().getContentResolver().notifyChange(uri, null);

标签: android android-contentprovider android-sqlite


【解决方案1】:

您不能在您的服务中禁用此机制。但是您应该尝试使用ContentProviderOperations 对它们进行批处理。

我写了一个introductory post about ContentProviderOperations 和另外两个帖子,分别介绍了withYieldAllowed()withBackReference() 方法。

对于您在此处描述的内容,尤其是后者应该很感兴趣。

使用 ContentProviderOperations,您可以批量更新和插入。如果您随后在 ContentResolver 对象上调用 applyBatch(),则 ContentProvider 会立即执行它们。

现在我从未使用过 Nicolas Klein 的生成器,但由于他是一位非常非常精通 Android 开发人员并在 Google 工作,我敢打赌生成的代码使用了事务调用notifyChange()最后整个批次只有一次。

正是您需要的。

【讨论】:

  • 我们正在讨论的代码是this one,我认为 Nicolas 没有在其中放置任何通知,因为没有表级 Uri 需要通知,就像任何给定的一样Operation 可以在任何Uri 上工作。我说的对吗?
  • 您可以使用通用 URI。这就是 ContactsContract 和 CalendarContract 正在做的事情。他们在 applyBatch 结束时分别使用CalendarContract.CONTENT_URIContactsContract.AUTHORITY_URI 通知您。我建议在生成的代码中添加这样的内容。
  • 如果我能够应用一批模拟INSERT OR UPDATE 的操作,我可以轻松地通知ContentProvider 之外的更改。您认为扩展ContentProviderOperation 并构建自定义InsertOrUpdate 操作是否可行?这将解决它而不会弄乱生成的代码。
  • 更新:不幸的是,它不能解决任何问题,因为 apply 方法 simply calls provider.insert, provider.update, provider.delete 委托通知到insertupdatedeleteContentProvider 实现。
  • 实际上 CalendarContract 和 ContactsContract 正在做的事情有点复杂。它们存储批处理是否正在执行。如果是这样,则不要在每个插入/更新/删除方法中通知。 See for example CalendarContract's method. 但你是对的,每个 ContentProvider 操作都会调用应用。我偏离了轨道。对不起!
【解决方案2】:

你能用你自己的 ContentResolver 代替吗?

您可以尝试使用自己的类扩展 ContentResolver,然后您可以覆盖方法 notifyChange 并在那里实现您的逻辑。

【讨论】:

  • 问题是我在notifyChange 中没有关于已执行操作的信息,因为它可能是需要通知的常规操作或不需要通知的“批量”操作。跨度>
【解决方案3】:

在您的内容提供程序类中,在返回光标之前在 query() 方法中,只需注释看起来像这样的代码

cursor.setNotificationUri(getContext().getContentResolver(), uri);

【讨论】:

  • 是的,但我正在寻找一种在不修改生成的代码/生成器的情况下获得相同结果的方法。
猜你喜欢
  • 1970-01-01
  • 2012-05-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多