Android 插入5000+;安卓联系人
我意识到这在很多地方都有所涉及,包括堆栈溢出,但我正在寻找人们可能使用的任何其他解决方案。所以考虑到这一点 我正在开发一个应用程序,用户可以首先将所有联系人与桌面应用程序同步。这是通过web服务调用完成的,该调用从服务器获取一组100个联系人,下载并解析信息,将联系人插入Android联系人数据库,确认收到这些联系人,然后对下一组100个联系人重复前面的步骤,直到同步完成。当用户拥有订单上的联系人或1000-2000个联系人时,此过程非常有效,但此应用程序的典型用户可以轻松拥有5000-6000个联系人(超级用户拥有10000个以上的联系人),在这种情况下,所需时间远比我希望的长。例如,大约5300个联系人的样本集可能需要13.5分钟才能完成。不错,但我希望它至少和iOS一样高效,如果可能的话,iOS可以为相同的数据集运行大约8分钟 我已经记录了每一步所需的时间,毫不奇怪,瓶颈似乎是将数据插入安卓合约数据库。在浏览网页后,我发现插入数千个联系人几乎没有什么帮助,但我发现的内容似乎分为以下三类: 1) ContentProviderOperation——谷歌推荐的方式,它给了我5300个联系人13.5分钟的基线时间 2) 批量插入——我读到builkInsert往往比applyBatch更有效,但当我自己尝试实现时,对于相同的5300个联系人,实际上需要25分钟。我觉得这很大程度上是因为我需要插入RAW联系人信息,然后保存生成的URI,以用于创建ContactsContract.Data for bulkInsert,这更自然地通过ContentProviderOperation中的backValueReference实现。此外,我查看了android源代码,并没有感觉到bulkInsert非常高效 3) 使用DatabaseUtils.InsertHelper和事务创建优化的批量插入——不幸的是,这似乎是面向那些创建自己的内容提供商的人的,因为您需要访问底层数据库作为实例变量,而我还没有看到如何使用本机contacts数据库实现这一点Android 插入5000+;安卓联系人,android,contacts,Android,Contacts,我意识到这在很多地方都有所涉及,包括堆栈溢出,但我正在寻找人们可能使用的任何其他解决方案。所以考虑到这一点 我正在开发一个应用程序,用户可以首先将所有联系人与桌面应用程序同步。这是通过web服务调用完成的,该调用从服务器获取一组100个联系人,下载并解析信息,将联系人插入Android联系人数据库,确认收到这些联系人,然后对下一组100个联系人重复前面的步骤,直到同步完成。当用户拥有订单上的联系人或1000-2000个联系人时,此过程非常有效,但此应用程序的典型用户可以轻松拥有5000-6000
有没有人有过插入5000多个联系人的经验,或者有任何其他可能的想法可以帮助我缩短时间?还是应该将ContentProviderOperation视为将要得到的优化?不幸的是,我认为1是最好的选择。我怀疑与iPhone相比,您的大部分开销都是内容提供商设计固有的跨进程IPC 你对3的分析是正确的
根设备上有一些选项可供内容提供商使用,但我怀疑这正是您想要的。您好,我在几分钟内插入了大量联系人我的代码是:
public void insertContact(contactList:List<Contact>){
val queueSize = 300 //400
val contactQueue = contactList.size/queueSize
if(contactQueue > 0) {
var startIndex = 0
var endIndex = 0
var tempList: List<Request.ContactBean>? = null
totalQueue = contactQueue + 1+smsQueue
for (i in 0..contactQueue) {
startIndex = i * queueSize
endIndex = startIndex + queueSize
endIndex = if (endIndex < contactList.size) endIndex else contactList.size
tempList = contactList.subList(startIndex, endIndex);
Log.d(Constant.TAG_RESTORE, "In loop totalQueue: " + contactQueue + " i: " + i
+ " startIndex: " + startIndex + "endIndex: " + endIndex + " Queuesize: " + tempList.size)
restoreContact(tempList);
}
}else{
totalQueue = 1+smsQueue;
restoreContact(contactList);
}
}
private fun restoreContact( contactList: List<Request.ContactBean>) {
Observable.fromCallable { insertContact(contactList); }
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
totalCompleteOperation++
if(totalCompleteOperation === totalQueue){
Log.d(Constant.TAG_RESTORE, " in subscribe restoreContact " +
"totalCompleteOperation: "+ totalCompleteOperation +" totalQueue "+totalQueue)
hideDialog();
completeRestore(true)
}
}
)
}
public void insertContact(List<Request.ContactBean> contacts) throws RemoteException, OperationApplicationException {
final int MAX_OPERATIONS_FOR_INSERTION = 100; //100
int size = contacts.size();
ArrayList<ContentProviderOperation> ops = new ArrayList<>();
for (int i = 0; i < size; i++) {
createOperations(ops, contacts.get(i));
if (ops.size() >= MAX_OPERATIONS_FOR_INSERTION) {
mContext.getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
ops.clear();
}
}
if (ops.size() > 0)
mContext.getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
}
private void createOperations(ArrayList<ContentProviderOperation> ops,
Request.ContactBean contact){
int backReference = ops.size();
ops.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null)
.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, null)
.withValue(ContactsContract.RawContacts.AGGREGATION_MODE, ContactsContract.RawContacts.AGGREGATION_MODE_DISABLED)
.build()
);
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
// .withYieldAllowed(true)
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, backReference)
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, contact.getName())
.build());
if (contact.getNumbers() != null && contact.getNumbers().size() > 0) {
// Adding insert operation to operations list
// to insert Mobile Number in the table ContactsContract.Data
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
//.withYieldAllowed(true)
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, backReference)
.withValue(ContactsContract.Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE)
.withValue(Phone.NUMBER, contact.getNumbers().get(0).getNumber())
.withValue(Phone.TYPE, Phone.TYPE_MOBILE)
.build());
if (contact.getNumbers().size() > 1) {
// Adding insert operation to operations list
// to insert Home Phone Number in the table ContactsContract.Data
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
//.withYieldAllowed(true)
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, backReference)
.withValue(ContactsContract.Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE)
.withValue(Phone.NUMBER, contact.getNumbers().get(1).getNumber())
.withValue(Phone.TYPE, Phone.TYPE_HOME)
.build());
}
}
if (contact.getEmails() != null && contact.getEmails().size() > 0) {
// Adding insert operation to operations list
// to insert Work Email in the table ContactsContract.Data
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
// .withYieldAllowed(true)
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, backReference)
.withValue(ContactsContract.Data.MIMETYPE, Email.CONTENT_ITEM_TYPE)
.withValue(Email.ADDRESS, contact.getEmails().get(0).getAddress())
.withValue(Email.TYPE, Email.TYPE_WORK)
.build());
}
if (contact.getEmails().size() > 1) {
// Adding insert operation to operations list
// to insert Home Email in the table ContactsContract.Data
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
// .withYieldAllowed(true)
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, backReference)
.withValue(ContactsContract.Data.MIMETYPE, Email.CONTENT_ITEM_TYPE)
.withValue(Email.ADDRESS, contact.getEmails().get(1).getAddress())
.withValue(Email.TYPE, Email.TYPE_HOME)
.build());
}
}
This code will insert huge contact list in very less time.
public void insertContact(联系人列表:列表){
val queueSize=300//400
val contactQueue=contactList.size/queueSize
如果(contactQueue>0){
var startIndex=0
var endIndex=0
变量模板列表:列表?=null
totalQueue=contactQueue+1+smsQueue
用于(0..contactQueue中的i){
startIndex=i*queueSize
endIndex=startIndex+queueSize
endIndex=if(endIndex=插入的最大操作数){
mContext.getContentResolver().applyBatch(contacts contract.AUTHORITY,ops);
ops.clear();
}
}
如果(ops.size()>0)
mContext.getContentResolver().applyBatch(contacts contract.AUTHORITY,ops);
}
专用操作(ArrayList操作,
Request.ContactBean(联系人){
int backReference=ops.size();
添加(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT\u URI)
.withValue(contacts contract.raw contacts.ACCOUNT\u NAME,null)
.带值(contacts contract.RawC