我正在开发一个REST应用程序来批量删除联系人(我的意思是联系人,而不是原始联系人)。删除一批约116个联系人需要3分钟以上,这在我看来很多。有时会打印Contacts deleted
,但它们仍然在手机的联系人列表中,有时则会被删除。
有人能指出我的问题在哪里吗?
我收到一个JSONArray
,其中包含要删除的联系人ID(以及其他一些细节,但只有在此方法中使用的ID)。
这是我的删除联系人代码:
public Boolean deleteBatchContact(final JSONArray jsonArray) throws JSONException, RemoteException, OperationApplicationException
{
final ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
final Long startTime = System.currentTimeMillis();
if(jsonArray.length() != 0) // there must be something in the JSONArray
{
for(int i = 0; i < jsonArray.length(); i++)
{
final JSONObject jsonContactObject = jsonArray.getJSONObject(i);
final String contactId = jsonContactObject.getString("id");
Long id = Long.parseLong(contactId);
ops.add(ContentProviderOperation.newDelete(ContentUris.withAppendedId(Contacts.CONTENT_URI, Long.parseLong(contactId)))
.withYieldAllowed(true)
.build());
}
try {
final ContentProviderResult[] cpr = contentResolver.applyBatch(ContactsContract.AUTHORITY, ops);
final Long endTimeTry = System.currentTimeMillis();
final Integer numberOfContactsDeleted = cpr.length;
if(numberOfContactsDeleted > 0)
{
Log.d(TAG, numberOfContactsDeleted + " Contacts deleted!");
final Long totalSuccess = endTimeTry-startTime;
Log.d(TAG, "Total Time (Sucess): " + totalSuccess);
return true;
}
else
{
Log.d(TAG, "Menor ou igual a zero...");
final Long totalFailed = endTimeTry-startTime;
Log.d(TAG, "Total Time (No deletes): " + totalFailed);
return false;
}
} catch (Exception e) {
Log.d(TAG, "deleteBatchContact: " + e.getMessage());
return false;
}
}
Long endTimeReturnFalse = System.currentTimeMillis();
Long totalTimeReturnFalse = endTimeReturnFalse - startTime;
Log.d(TAG, "Total time return false: " + totalTimeReturnFalse);
return false;
}
这就是我调用deleteBatchContact
方法的地方:
else if(type.equalsIgnoreCase("delete"))
{
Log.d(TAG, "DELETE REQUEST");
String strJson = request.getEntityAsText();
int age = response.getAge();
Log.d(TAG, "age1: " + age);
Log.d(TAG, "is commited1? " + response.isCommitted());
try {
Log.d(TAG, "Try...");
JSONArray jsonArray = new JSONArray(strJson);
if(processDelete(jsonArray) == true)
{
Log.d(TAG, "Response -> Deleted with Success!");
response.setEntity("Deleted with success!", MediaType.TEXT_ALL);
age = response.getAge();
Log.d(TAG, "age2: " + age);
Log.d(TAG, "is commited2? " + response.isCommitted());
}
else
{
Log.d(TAG, "Response -> No contacts deleted...");
response.setEntity("No contacts deleted...", MediaType.TEXT_ALL);
age = response.getAge();
Log.d(TAG, "age3: " + age);
Log.d(TAG, "is commited3? " + response.isCommitted());
}
} catch (RemoteException e) {
Log.d(TAG, "processDelete exception: " + e.getMessage());
e.printStackTrace();
} catch (JSONException e) {
Log.d(TAG, "processDelete exception: " + e.getMessage());
e.printStackTrace();
} catch (OperationApplicationException e) {
Log.d(TAG, "processDelete exception: " + e.getMessage());
e.printStackTrace();
}
}
这是输出:
02-13 01:28:04.484: D/ContactRestlet(17638): DELETE REQUEST
02-13 01:28:04.507: D/ContactRestlet(17638): age1: 0
02-13 01:28:04.507: D/ContactRestlet(17638): is commited1? false
02-13 01:28:04.507: D/ContactRestlet(17638): Try...
02-13 01:30:04.671: D/ContactRestlet(17638): DELETE REQUEST
02-13 01:30:04.671: D/ContactRestlet(17638): age1: 0
02-13 01:30:04.671: D/ContactRestlet(17638): is commited1? false
02-13 01:30:04.671: D/ContactRestlet(17638): Try...
02-13 01:31:07.468: D/ContactList(17638): 116 Contacts deleted!
02-13 01:31:07.468: D/ContactList(17638): Total Time (Sucess): 182911
02-13 01:31:07.468: D/ContactRestlet(17638): Response -> Deleted with Success!
02-13 01:31:07.472: D/ContactRestlet(17638): age2: 0
02-13 01:31:07.472: D/ContactRestlet(17638): is commited2? false
02-13 01:31:07.476: W/System.err(17638): 2014-02-13 01:31:07 - - - 8080 DELETE /contacts - 1001 21 12590 62837 http://10.17.1.72:8080 Apache-HttpClient/4.3.1 (java 1.5) -
修改 正如@RocketRandom所建议的,这是我的新代码:
public Boolean deleteBatchContact(final JSONArray jsonArray) throws JSONException, RemoteException, OperationApplicationException
{
final ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
final Long startTime = System.currentTimeMillis();
if(jsonArray.length() != 0) // there must be something in the JSONArray
{
StringBuilder query = new StringBuilder(" in {");
for(int i = 0; i < jsonArray.length(); i++)
{
final JSONObject jsonContactObject = jsonArray.getJSONObject(i);
final String contactId = jsonContactObject.getString("id");
query.append(contactId).append(",");
}
query.deleteCharAt(query.length()-1);
query.append("}");
ops.add(ContentProviderOperation.newDelete(Contacts.CONTENT_URI)
.withSelection(Contacts._ID + " in { 1 , 2 , 3 , 4 , 5, 6, 7, 8, 9}", null).build());
try {
final ContentProviderResult[] cpr = contentResolver.applyBatch(ContactsContract.AUTHORITY, ops);
final Long endTimeTry = System.currentTimeMillis();
final Integer numberOfContactsDeleted = cpr.length;
if(numberOfContactsDeleted > 0)
{
Log.d(TAG, numberOfContactsDeleted + " Contacts deleted!");
final Long totalSuccess = endTimeTry-startTime;
Log.d(TAG, "Total Time (Sucess): " + totalSuccess);
return true;
}
else
{
Log.d(TAG, "Menor ou igual a zero...");
final Long totalFailed = endTimeTry-startTime;
Log.d(TAG, "Total Time (No deletes): " + totalFailed);
return false;
}
} catch (Exception e) {
Log.d(TAG, "deleteBatchContact: " + e.getMessage());
return false;
}
}
Long endTimeReturnFalse = System.currentTimeMillis();
Long totalTimeReturnFalse = endTimeReturnFalse - startTime;
Log.d(TAG, "Total time return false: " + totalTimeReturnFalse);
return false;
}
这是输出:
03-06 01:42:10.367: D/ContactList(8925): 1 Contacts deleted!
03-06 01:42:10.367: D/ContactList(8925): Total Time (Sucess): 84
现在它没有删除任何联系人,你能发现错误在哪里吗? 即使它说删除了一个联系人,也没有删除。所有这些联系ID都是有效的(它们存在于我的联系人表中,我已经从我的设备上下载并检查它。)
答案 0 :(得分:1)
编辑:删除了之前建议的解决方案。这是行不通的。 (对不起)
我检查了联系人提供商代码,只有原始联系人支持批量删除。对于联系人他们在那里所做的只是返回,他们在那里有一个不错的小“TODO”。
您的原始代码是正确的方法。 当您删除联系人(没有isCallerSyncAdapter标志)时,提供程序执行的操作是查询具有该联系人ID的所有原始联系人并逐个设置脏标记(这需要一段时间)
我在我的结尾尝试了:
03-19 13:28:11.620:D / tmp(5912):188联系人被删除!
03-19 13:28:11.620:D / tmp(5912):总时间(成功):387496
即每次接触大约需要2秒钟,这太可怕了。 但是,如果不修改Android Contacts ContentProvider
,我就没有办法让它更快