以编程方式批量添加数千个Android联系人

6
使用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将这些内容插入Data表中
问题:
- 在第二种方法中,我首先对RawContacts表条目执行applyBatch,然后对Data表条目执行bulkInsert。这是因为我找不到一种方式来提供Data条目的原始联系人ID。是否有类似于backreferences的bulkInsert功能,可以让我同时添加RawContacts和Data条目? - applyBatch和bulkInsert在一批操作中只能执行很多次插入,否则它们会抱怨事务过大。因此,它们必须每500个联系人左右应用一次。是否有一种方法可以更改此限制? - 是否有一种完全不同且更快的方式可以一次性添加成千上万个联系人?
1个回答

0

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

由于你在同一个批处理操作中同时插入到RawContactsData,如果出现任何问题,数据库将回滚该批次上的先前更改,因此你不会在任何表中留下任何僵尸信息。

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

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


谢谢,我会尝试一下。但是我有点困惑,因为我的测试显示实现方式#1和#2相比,#2几乎快了一倍。不过,我可以理解强度论点。 - UtterlyConfused
由于某种原因,当我在不同的线程上执行applyBatch时,批处理必须更小,否则会出现“TransactionTooLargeException”异常。当我将批处理大小减小到可接受的范围时,最终速度与同步执行所有操作相比并没有提高。也许这是由ContentResolver所强制实施的? - UtterlyConfused

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接