2017-10-08 15 views
0

このアプリケーションでは、SQLLiteデータベース、PHONE.CONTACTSへのクエリ、およびネストされたwhileループを以下に示すように取り入れています。基本的には、電話機のすべての連絡先がカスタムリストビューに一覧表示されます。私がアプリケーションをテストすると、約1分ほどリストビューが読み込まれます。その背後にある理由は何ですか?それは背景スレッドではなくUIスレッドでクエリを実行しているためですか?またはwhileループ内でSQLLite update()メソッドを使用すると高価ですか?またはRegExのために?これが正しい方法でない場合は、適切なアプローチを教えてください。私はあなたの答えに感謝します。リストビューの起動が遅すぎる

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.beginTransaction();' 'だけsqlDbWrite.setTransactionSuccessful()とループ、前に、ループ終了時'; 'と' sqlDbWrite.endTransaction()。トランザクションに関する詳細については、[SQLiteDatabase](https://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html)をご覧ください。 – MikeT

+0

実際に達成したいことは何ですか? – pskink

+0

@pskink連絡先の名前と電話番号を電話データベースから取得し、ポイント、電話番号の列を持つ独自のカスタムデータベースを持っています。カスタムデータベースと電話連絡先データベース間の電話番号の一致にネストされたwhileループを使用しています。それ。最近の呼び出しを確認するためのCallLog DBクエリもありますが、CallLog-Own Databaseの照合は行いませんでしたが、ここでループコードを使用すると問題は複雑になりません。 CallLogとContacsデータベースの番号形式が異なるためです。 – barutto

答えて

2
  1. バックグラウンドスレッドへのデータベース操作は、これを達成するためにLoaderManagerとCursorLoaderを実装する使用します。
  2. LoaderManager実装のOnLoadFinished()コールバックでlistAdapterを更新する処理を処理します。

ローダー上のドキュメントとLoaderManager
Loaders

、ここでの使用には、連絡先プロバイダからデータを取得するためにCursorLoaderを使用してアンドロイドのチュートリアルです。

Retrieving a List of Contacts
1
  1. あなたがバックグラウンドスレッドでの連絡先を取得する必要があります。
  2. RecyclerViewを(おそらく)そのような長いリストのために使用してください。負荷オフ