Android4.1联系人模块在删除大量联系人时,反应比较慢,删一段时间后,没删除完成界面自动返回,或者出现黑屏,还有可能提示“Unfortunately,Contacts has stopped.”。对于这个问题的处理,修改文件packages/apps/Contacts/src/com/android/contacts/editor/MultiPickContactActivity.java
import android.net.Uri.Builder;
import android.os.Bundle;
import android.os.Looper;
+import android.provider.CallLog;
import android.provider.ContactsContract;
import android.provider.ContactsContract.ContactCounts;
import android.provider.Settings;
private final int COLUMN_NUMBER = 1;
private final int COLUMN_NAME = 2;
+ private ArrayList<ContentProviderOperation> mOpsCalls = null;
+
+ private ArrayList<ContentProviderOperation> mOpsContacts = null;
+
public DeleteContactsThread() {
super("DeleteContactsThread");
}
Bundle choiceSet = (Bundle) mChoiceSet.clone();
Set<String> keySet = choiceSet.keySet();
Iterator<String> it = keySet.iterator();
+
+ android.content.ContentProviderOperation.Builder builder = null;
+
+ ContentProviderOperation cpo = null;
+
+ // Current contact count we can delete.
+ int count = 0;
+
+ // The contacts we batch delete once.
+ final int BATCH_DELETE_CONTACT_NUMBER = 100;
+
+ mOpsCalls = new ArrayList<ContentProviderOperation>();
+ mOpsContacts = new ArrayList<ContentProviderOperation>();
+
while (!mCanceled && it.hasNext()) {
String id = it.next();
Uri uri = null;
if (isPickCall()) {
uri = Uri.withAppendedPath(Calls.CONTENT_URI, id);
+ builder = ContentProviderOperation.newDelete(uri);
+ cpo = builder.build();
+ mOpsCalls.add(cpo);
}else{
uri = Uri.withAppendedPath(Contacts.CONTENT_URI, id);
long longId = Long.parseLong(id);
continue;
}
}
+ builder = ContentProviderOperation.newDelete(uri);
+ cpo = builder.build();
+ mOpsContacts.add(cpo);
}
+ // If contacts more than 2000, delete all contacts
+ // one by one will cause UI nonresponse.
+// resolver.delete(uri, null, null);
mProgressDialog.incrementProgressBy(1);
+ // We batch delete contacts every 100.
+ if (count % BATCH_DELETE_CONTACT_NUMBER == 0){
+ batchDelete();
+ }
+ count ++;
}
+
+ batchDelete();
+ mOpsCalls = null;
+ mOpsContacts = null;
Log.d(TAG, "DeleteContactsThread run, progress:" + mProgressDialog.getProgress());
mProgressDialog.dismiss();
finish();
}
+ /**
+ * Batch delete contacts more efficient than one by one.
+ */
+ private void batchDelete(){
+ try {
+ mContext.getContentResolver().applyBatch(CallLog.AUTHORITY, mOpsCalls);
+ mContext.getContentResolver().applyBatch(ContactsContract.AUTHORITY, mOpsContacts);
+ mOpsCalls.clear();
+ mOpsContacts.clear();
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ } catch (OperationApplicationException e) {
+ e.printStackTrace();
+ }
+ }
+
public void onCancel(DialogInterface dialog) {
mCanceled = true;
Log.d(TAG, "DeleteContactsThread onCancel, progress:" + mProgressDialog.getProgress());