barutto
barutto

Reputation: 104

Android App With ListView Launching Too Slow

This app I am working on includes a SQLLite Database, a query to PHONE.CONTACTS and nested while loops as shown below. It basically lists all the contacts on the phone in a custom list view. When I test the app, the list view loads around one minute or so. Could you please tell me what's the reason behind that? Is it because I am having the queries on UI Thread instead of a background Thread? or using SQLLite update() method inside a while loop is too expensive? or because of RegEx? If this is not the right way to do it then could you please advise me the right approach? I'd appreciate your answer.

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);
}

Upvotes: 0

Views: 85

Answers (2)

Andrew Lam
Andrew Lam

Reputation: 1391

  1. off load the database operation to a background thread, use implement a CursorLoader with the LoaderManager to accomplish this.
  2. Handle updating the listAdapter in the OnLoadFinished() callback of the LoaderManager implementation.

Documentation on Loaders and the use of LoaderManager
Loaders

and here is the android walkthrough that uses a CursorLoader to retrieve data from the contacts provider. Retrieving a List of Contacts

Upvotes: 2

Shmuel
Shmuel

Reputation: 518

  1. You should get the contacts in background thread.
  2. Use RecyclerView for (probably) such a long lists.

Upvotes: 1

Related Questions