2017-10-08 93 views
0

我正在处理的这个应用程序包括一个SQLLite数据库,一个查询PHONE.CONTACTS和嵌套while循环,如下所示。它基本上列出了在自定义列表视图中的手机上的所有联系人。当我测试应用程序时,列表视图加载大约一分钟左右。你能告诉我这背后的原因是什么?是因为我在UI线程上查询而不是后台线程?或者在while循环中使用SQLLite update()方法太昂贵了?还是因为RegEx?如果这不是正确的做法,那么你能否告诉我正确的方法?我会很感激你的回答。ListView启动速度太慢的Android应用程序

MainFragment.java:

//SINGLETON 
personDataList = PersonDataSingleton.getInstance().getPersonDataList(); 

//DATABASE 
db = new DatabaseHelper(getActivity().getApplicationContext()); 
sqlDbWrite = db.getWritableDatabase(); 
values = new ContentValues(); 
ContentValues timeValues = new ContentValues(); 
sqlDbRead = db.getReadableDatabase(); 

//QUERIES 
cursorProjection = new String[]{DatabaseHelper.COLUMN_SOCIAL_POINT, DatabaseHelper.COLUMN_LOOKUP}; 
cursorTest = sqlDbRead.query(DatabaseHelper.DATABASE_TABLE, cursorProjection, null, null, null, null, DatabaseHelper.COLUMN_SOCIAL_POINT + " DESC"); 

mProjection = new String[]{ContactsContract.CommonDataKinds.Phone.NUMBER,ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, ContactsContract.Contacts.PHOTO_THUMBNAIL_URI}; 
mCursor = getActivity().getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, mProjection, null, null, null, null); 

//COLUMN INDICES 
int testStringIndex = cursorTest.getColumnIndexOrThrow(DatabaseHelper.COLUMN_SOCIAL_POINT); 
int testContactsNumberIndex = cursorTest.getColumnIndexOrThrow(DatabaseHelper.COLUMN_LOOKUP); 
int contactNameIndex = mCursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME); 
int contactsNumberIndex = mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER); 
int mThumbNailUriIndex = mCursor.getColumnIndex(ContactsContract.Contacts.PHOTO_THUMBNAIL_URI); 

//NESTED WHILE LOOPS 
cursorTest.moveToPosition(-1); 
while (cursorTest.moveToNext()) 
{ 
    testString = cursorTest.getInt(testStringIndex); 
    String testContactsNumber = cursorTest.getString(testContactsNumberIndex); 

    if (subtractPoint > 1) 
    { 
    testString = testString - daysSince; 
    timeValues.put(DatabaseHelper.COLUMN_SOCIAL_POINT, testString); 
    sqlDbWrite.update(DatabaseHelper.DATABASE_TABLE, timeValues, DatabaseHelper.COLUMN_LOOKUP + "=?", new String[]{testContactsNumber}); 
    } 

    mCursor.moveToPosition(-1); 
    while (mCursor.moveToNext()) 
    { 
    contactName = mCursor.getString(contactNameIndex); 
    contactsNumber = mCursor.getString(contactsNumberIndex);    
    mThumbNailUri = mCursor.getString(mThumbNailUriIndex); 
    revisedContactsNumber = contactsNumber.replaceAll("\\D+", ""); 

     if (revisedContactsNumber.equals(testContactsNumber)) 
     { 
     personDataList.add(new PersonData(contactName, contactsNumber, mThumbNailUri, testString, "01")); 
     } 
    } 
} 

//ARRAY ADAPTER 
@Override 
public void onActivityCreated(Bundle savedInstanceState) 
{ 
super.onActivityCreated(savedInstanceState); 
mCustomAdapter = new CustomAdapter1(getActivity(), personDataList); 
setListAdapter(mCustomAdapter); 
} 
+0

尝试在循环完成前使用'sqlDbWrite.setTransactionSuccessful();'和'sqlDbWrite.endTransaction();'来添加'sqlDbWrite.beginTransaction();'。您可能还想查看[SQLiteDatabase](https://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html)以了解有关事务的更多信息。 – MikeT

+0

你想实现什么目标? – pskink

+0

@pskink我从手机数据库中提取联系人姓名和号码,并拥有自己的自定义数据库,包括点数,电话号码列。我使用嵌套while循环在自定义数据库和电话联系人数据库之间匹配电话号码,并根据那。还有一个CallLog DB查询来检查最近的调用,但我没有把CallLog - Own数据库匹配,while循环代码在这里不会复杂的问题,因为我几乎可以肯定慢的是因为如果这嵌套while循环。我使用正则表达式因为CallLog和Contacs数据库的数字格式不同。 – barutto

回答

2
  1. 开路数据库操作后台线程,可使用实现与LoaderManager一个CursorLoader做到这一点。
  2. 处理更新LoaderManager实现的OnLoadFinished()回调中的listAdapter。装载机

文档和使用LoaderManager
Loaders

这里是使用CursorLoader来检索联系人提供的数据android的演练。 Retrieving a List of Contacts

1
  1. 你应该在后台线程中的联系人。
  2. 使用RecyclerView作为(可能)如此长的列表。