Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Cursor - moveToNext() doesnt seem to go to end of cursor

Why doesnt my Android Cursor go all the way to the end of the original "promise"??

My cursor.getCount() differs from my last cursor.getPosition(). Check my while loop! It is all I do with it!

Notes: 1. it is about querying the Contacts content provider (android api >5) 2. I display only the esential code

Cursor cursor = mContext.getContentResolver().query(mUri, mProjections, null, null, null);
Logger.d(TAG, "***  cursor.getCount(): "+cursor.getCount());
while (cursor.moveToNext()) {
    Logger.d(TAG, "| position: "+cursor.getPosition());
    processMainCursor(serializer, cursor);
}
cursor.close();

processMainCursor() will display data from cursor + do another queries: one 4 phones, one 4 emails, one 4 IM accounts:

void processMainCursor(XmlSerializer serializer, Cursor main_cursor) {
     writeCursorData(serializer, main_cursor); //writes cursor data, column by column
     writePhoneEntities(serializer, main_cursor);
     writeEmailEntities(serializer, main_cursor);
     writeIMEntities(serializer, main_cursor);
}

In none of my writeXXX methods do i close my main_cursor or move next!!!..have to trust me on that.. i just do a new query, print data & close that cursor

So statistics:

  • cursor.getCount() = 695 (always)
  • commenting writePhoneEntities, writeEmailEntities, writeIMEntities: cursor.getCount() = last cursor.getPosition() = 695 (so correct!)
  • leaving one/two/all of my writeXEntities shows randomness; example: leaving them all: last cursor.getPosition() sometimes displays 254, 257, 253, etc; leaving just phone & IM: 514, 510, 511, etc (so different RUN -> different last cursor.getPosition() VALUE)

So oppinions.. Why is that? Is it memory related?

Update: Leaving any of my writeXEntities displays at the end in logcat: Removing dead content provider: contacts

Update 2 Adding cursor.moveToFirst(); & doing loop like

do {
    //do whatever you want
} while (cursor.moveToNext()); 

didn't do the job..

So maybe the answer is in this logcat entries:

05-21 23:29:30.209: I/ActivityThread(7085): Removing dead content provider: contacts
05-21 23:29:30.209: I/ActivityThread(7085): Removing dead content provider: com.android.contacts

SAMPLE OF a writeXEntity REMOVED

SOLUTION .. i wasnt closing the cursors from writeXEntity corectly (probably leaving quite a lot of open cursor after main while)

in reality i was closing like this

if(phone_cursor!=null && phone_cursor.getCount() > 0)
{                   
     //... stuff
     phone_cursor.close();
}

i should have closed after if

if(phone_cursor!=null && phone_cursor.getCount() > 0)
{                   
     //... stuff
}
phone_cursor.close();

I guess leaving a basilion cursor open ..was the answer?!?

like image 507
pulancheck1988 Avatar asked Sep 05 '25 15:09

pulancheck1988


1 Answers

You need to move the cursor to the first row. Try adding cur.moveToFirst() before the while loop.

You might also consider using a do-while loop. This will ensure that you never skip over the first row in the cursor:

if (cursor.moveToFirst()) {
    do {
        //do whatever you want
    } while (cursor.moveToNext());               
}
cursor.close();
like image 151
Alex Lockwood Avatar answered Sep 09 '25 22:09

Alex Lockwood