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

时间:2017-04-19 13:09:39

标签: android android-contacts android-contentresolver

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

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

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

对于每个联系人:

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

最后,使用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 个答案:

答案 0 :(得分:0)

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

当您在同一批处理操作中同时插入Datafor (CoreMap sentence : sentences) { List<MatchedExpression> matched = extractor.extractExpressions(sentence); if (matched != null) { matched = MatchedExpression.removeNested(matched); matched = MatchedExpression.removeNullValues(matched); System.out.print("FOR SENTENCE:" + sentence); } for(MatchedExpression phrase : matched){ // Print out matched text and value System.out.print("MATCHED ENTITY: " + phrase.getText()+ "\t" + "VALUE: " + phrase.getValue()); 时,如果在此过程中出现问题,数据库将回滚该批处理中的先前更改,因此您不会在任一表中留下任何 zombie 信息。

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

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