【问题标题】:Programmatically adding thousands of Android contacts in bulk以编程方式批量添加数千个 Android 联系人
【发布时间】:2017-09-15 17:48:00
【问题描述】:

使用 ContentResolver.applyBatch 和 ContentResolver.bulkInsert 方法一次性添加数千个联系人非常慢。 Android 是否提供了一种更快的批量添加联系人的不同方式?

到目前为止,我已经尝试了以下方法:

使用 applyBatch(每千个联系人约 75 秒)

对于每个联系人:

  • 创建一个新的 ContentValues 对象来表示原始联系人
  • 构建新的 ContentProviderOperation 以将其插入到 RawContacts 表中
  • 将此操作添加到列表并存储其索引
  • 为姓名和电话号码等其他联系人字段创建 ContentValues 对象
  • 构建一个新的 ContentProviderOperation 以将这些中的每一个插入到 Data 表中,并反向引用原始联系人插入操作
  • 将这些操作添加到列表中

最后,使用 ContentResolver.applyBatch 应用所有操作。

使用 bulkInsert(每千个联系人约 40 秒)

对于每个联系人:

  • 创建一个新的 ContentValues 对象来表示原始联系人
  • 构建新的 ContentProviderOperation 以将其插入到 RawContacts 表中
  • 将此操作添加到列表中

然后,使用 ContentResolver.applyBatch 应用所有操作。这将返回一个 ContentProviderResults 数组。

现在,对于每个联系人:

  • 从对应的 ContentProviderResult 解析原始联系人 ID。
  • 为联系人的所有数据字段构造一个 ContentValues 对象数组,每个字段都有一个用于原始联系人 ID 的字段
  • 使用 ContentResolver.bulkInsert 将这些插入数据表中

问题

  • 在第二种方法中,我首先对 RawContacts 表条目执行 applyBatch,然后对 Data 表条目执行 bulkInsert。这是因为我无法找到为数据条目提供原始联系人 ID 的方法。是否有类似于 bulkInsert 的反向引用的东西可以让我同时添加 RawContacts 和 Data 条目?
  • applyBatch 和 bulkInsert 只能在一批中执行这么多的插入操作,然后才会抱怨事务太大。因此,它们必须每 500 次左右接触一次。有没有办法改变这个限制?
  • 是否有一些完全不同的更快的方法可以同时添加数千个联系人?

【问题讨论】:

    标签: android android-contacts android-contentresolver


    【解决方案1】:

    您展示的第一种方法是正确的方法,除了比第二种方法更快之外,它也更安全。

    当您在同一个批处理操作中同时插入RawContactsData 时,如果在此过程中出现问题,数据库将回滚该批处理上先前的更改,因此您不会留下任何 zombie 任一表中的信息。

    为了加快速度,请尝试在不同线程之间划分工作。

    如果您有 1000 个联系人,请创建一个处理前 500 个的线程,并创建另一个处理后 500 个的线程,并让它们同时运行。 如果需要,您可以将其应用于更多线程。

    【讨论】:

    • 谢谢,我会试一试的。不过我有点困惑,因为我自己对实现 #1 和 #2 的测试表明 #2 的速度几乎是原来的两倍。但是,我可以欣赏稳健性论点。
    • 出于某种原因,当我在不同的线程上执行applyBatch 时,批次必须更小,否则我会得到TransactionTooLargeException。当我将批处理大小减小到可以接受的程度时,它最终不会比同步完成所有事情快。也许这是ContentResolver强加的?
    猜你喜欢
    • 1970-01-01
    • 2012-02-24
    • 2011-04-13
    • 1970-01-01
    • 1970-01-01
    • 2016-12-26
    • 2011-10-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多