Android联系人光标需要太多时间来迭代
Posted
技术标签:
【中文标题】Android联系人光标需要太多时间来迭代【英文标题】:Android Contact cursor take too much time to iterate 【发布时间】:2013-03-18 23:48:43 【问题描述】:我想从电话联系人应用程序中获取所有联系人并插入到本地 sqlite 数据库中。 但问题是android接触光标需要时间来迭代......
代码:
private Cursor getContacts()
// Run query
Uri uri = ContactsContract.Contacts.CONTENT_URI;
String[] projection = new String[] ContactsContract.Contacts._ID,
ContactsContract.Contacts.DISPLAY_NAME ;
String selection = ContactsContract.Contacts.IN_VISIBLE_GROUP + " = '"
+ ("1") + "'";
String[] selectionArgs = null;
String sortOrder = ContactsContract.Contacts.DISPLAY_NAME
+ " COLLATE LOCALIZED ASC";
return managedQuery(uri, projection, selection, selectionArgs,
sortOrder);
插入数据库:
long mStartTime = System.currentTimeMillis();
int batch = 50;
try
SQLiteDatabase db = this.getWritableDatabase();
// InsertHelper insertHelper = new InsertHelper(db,
// TABLE_USER_INFO);
// String insertSql =
// "INSERT INTO UserInfo (firstname,lastname,userid,serveruserid,phonenumber,emailaddress,street,state,city,country) VALUES (?,?,?,?,?,?,?,?,?,?) ";
// SQLiteStatement sqLiteStatement = db.compileStatement(insertSql);
if (cursor != null)
if (cursor.moveToFirst())
for (int i = 0; i < cursor.getCount() / batch
+ (((cursor.getCount() % batch) > 0) ? 1 : 0); i++)
mStartTime = System.currentTimeMillis();
StringBuilder sqlBuilder = new StringBuilder();
db.beginTransaction();
sqlBuilder
.append("INSERT INTO UserInfo (firstname,lastname,userid,serveruserid,phonenumber,emailaddress,street,state,city,country) ");
for (int j = 0; j < batch; j++)
String name = cursor
.getString(cursor
.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
long _id = cursor
.getLong(cursor
.getColumnIndex(ContactsContract.Contacts._ID));
// ADDRESS
Cursor address = context
.getContentResolver()
.query(ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.StructuredPostal.CONTACT_ID
+ " = " + _id, null, null);
String street = null, city = null, state = null, country = null;
while (address.moveToNext())
street = address
.getString(address
.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.STREET));
city = address
.getString(address
.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.CITY));
state = address
.getString(address
.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.REGION));
country = address
.getString(address
.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.COUNTRY));
// address.moveToNext()
address.close();
// PHONE NO
String phoneNumber = null;
Cursor phones = context
.getContentResolver()
.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID
+ " = " + _id, null, null);
while (phones.moveToNext())
phoneNumber = phones
.getString(phones
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
phones.close();
// EMAIL ID
String emailId = null;
Cursor emails = context
.getContentResolver()
.query(ContactsContract.CommonDataKinds.Email.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Email.CONTACT_ID
+ " = " + _id, null, null);
while (emails.moveToNext())
emailId = emails
.getString(emails
.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
emails.close();
// INSERT INTO DB
ContentValues values = new ContentValues();
String[] names = name.split(" ");
if (name != null && names.length == 1)
values.put(KEY_FIRST_NAME, name);
values.put(KEY_LAST_NAME, "");
else if (name != null && names.length > 1)
values.put(KEY_FIRST_NAME, names[0]);
values.put(KEY_LAST_NAME, names[1]);
// Log.d(TAG, "User Id:" + _id);
values.put(KEY_USER_LOCAL_ID, _id);
values.put(KEY_SERVER_USER_ID, "0");
if (phoneNumber != null
&& !phoneNumber.equalsIgnoreCase("0"))
// REPLACE "-" FROM PHONE NO
phoneNumber = phoneNumber.replace("-", "")
.trim();
values.put(KEY_PH_NO, IOUtils
.getFormatedPhoneNo(context,
phoneNumber));
Log.e(TAG, "Inserting contacts into db name:"
+ name + " Phone:" + phoneNumber);
if (emailId != null)
values.put(KEY_EMIAL, emailId);
if (street != null)
values.put(KEY_STREET, street);
if (state != null)
values.put(KEY_STATE, state);
if (city != null)
values.put(KEY_CITY, city);
if (country != null)
values.put(KEY_COUNTRY, country);
if (emailId == null && phoneNumber == null)
// Log.d(TAG, "email,ph no not found:" + name);
else
Log.e(TAG, "*** Name:" + name + " Email id:"
+ emailId + " phone:" + phoneNumber);
if (j == 0)
sqlBuilder.append(" SELECT ");
else
sqlBuilder.append(" UNION SELECT ");
sqlBuilder
.append("'"
+ values.getAsString(
KEY_FIRST_NAME)
.replace("'", "") + "'")
.append(" AS " + KEY_FIRST_NAME + ", ");
sqlBuilder.append(
"'"
+ values.getAsString(
KEY_LAST_NAME).replace(
"'", "") + "'").append(
" AS " + KEY_LAST_NAME + ", ");
sqlBuilder
.append("'"
+ values.getAsString(KEY_USER_LOCAL_ID)
+ "'")
.append(" AS " + KEY_USER_LOCAL_ID
+ ", ")
//
.append("'")
.append((values
.getAsString(KEY_SERVER_USER_ID) != null) ? values
.getAsString(KEY_SERVER_USER_ID)
: " ")
.append("'")
.append(" AS " + KEY_SERVER_USER_ID
+ ", ")
//
.append("'")
.append((values.getAsString(KEY_PH_NO) != null) ? values
.getAsString(KEY_PH_NO) : "")
.append("'")
.append(" AS " + KEY_PH_NO + ", ")
//
.append("'")
.append((values.getAsString(KEY_EMIAL) != null) ? values
.getAsString(KEY_EMIAL) : "")
.append("'")
.append(" AS " + KEY_EMIAL + ", ")
//
.append("'")
.append((values.getAsString(KEY_STREET) != null) ? values
.getAsString(KEY_STREET) : "")
.append("'")
.append(" AS " + KEY_STREET + ", ")
//
.append("'")
.append((values.getAsString(KEY_STATE) != null) ? values
.getAsString(KEY_STATE) : "")
.append("'")
.append(" AS " + KEY_STATE + ", ")
//
.append("'")
.append((values.getAsString(KEY_CITY) != null) ? values
.getAsString(KEY_CITY) : "")
.append("'")
.append(" AS " + KEY_CITY + ", ")
//
.append("'")
.append((values
.getAsString(KEY_COUNTRY) != null) ? values
.getAsString(KEY_COUNTRY) : "")
.append("'")
.append(" AS " + KEY_COUNTRY);
if (!cursor.moveToNext())
Log.d(TAG, "Cursor pos" + cursor.getPosition());
break;
// Log.d(TAG, "BUILDER: " + sqlBuilder.toString());
db.execSQL(sqlBuilder.toString());
db.setTransactionSuccessful();
db.endTransaction();
Log.e("Time:",
"operatio time"
+ (mStartTime - System
.currentTimeMillis()));
// CLOSE DB
db.close();
catch (Exception e)
e.printStackTrace();
finally
// insertHelper.c
插入需要 4 分钟....
请建议迭代光标的有效方法。
提前致谢。
【问题讨论】:
向我们展示你现在的表现。 【参考方案1】:使用managedQuery(...)
,您可以投射查询投影(以要提取的列数组的形式)并提取更大的数据。通过这样做,您可以缓解单独查询数据库的问题。这是这个过程中最大的要求。
此外,支持包 v4 中还有新的 CursorLoader
类,用于异步加载该数据。
此外,您可以使用moveToNext()
来迭代while
循环,因为游标总是在数据“之前”开始。
【讨论】:
以上是关于Android联系人光标需要太多时间来迭代的主要内容,如果未能解决你的问题,请参考以下文章
如何从 Android 联系人中的联系人 ID 获取只读帐户名称