以编程方式批量添加数千个 Android 联系人
Posted
技术标签:
【中文标题】以编程方式批量添加数千个 Android 联系人【英文标题】:Programmatically adding thousands of Android contacts in bulk 【发布时间】: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 次左右接触一次。有没有办法改变这个限制? 是否有一些完全不同的更快的方法可以同时添加数千个联系人?【问题讨论】:
【参考方案1】:您展示的第一种方法是正确的方法,除了比第二种方法更快之外,它也更安全。
当您在同一个批处理操作中同时插入RawContacts
和Data
时,如果在此过程中出现问题,数据库将回滚该批处理上先前的更改,因此您不会留下任何 zombie 任一表中的信息。
为了加快速度,请尝试在不同线程之间划分工作。
如果您有 1000 个联系人,请创建一个处理前 500 个的线程,并创建另一个处理后 500 个的线程,并让它们同时运行。 如果需要,您可以将其应用于更多线程。
【讨论】:
谢谢,我会试一试的。不过我有点困惑,因为我自己对实现 #1 和 #2 的测试表明 #2 的速度几乎是原来的两倍。但是,我可以欣赏稳健性论点。 出于某种原因,当我在不同的线程上执行applyBatch
时,批次必须更小,否则我会得到TransactionTooLargeException
。当我将批处理大小减小到可以接受的程度时,它最终不会比同步完成所有事情快。也许这是ContentResolver
强加的?以上是关于以编程方式批量添加数千个 Android 联系人的主要内容,如果未能解决你的问题,请参考以下文章