Search code examples
androidsqliteiteratorcursor

Iterate Through Cursor, moveToNext() Does Not Appear To Work


I'm running into a bit of a problem. I am trying to iterate through a cursor to pull out the needed data. However the moveToNext() methods does not seem to move the cursor past the first position. It will move to the first row of results no problem, but it seems like it will not go past that first row and returns true every time. Resulting in an infinite loop. Here is my code:

This methods adds a new item to the database:

public List<Items> getAllItems() {
    SQLiteDatabase db = getWritableDatabase();
    DatabaseParser parser = new DatabaseParser();

    Cursor result = db.rawQuery("SELECT * FROM " + TableName.ITEMS.getName(), null);
    List<Trip> items = parser.cursorToListOfItems(result);

    Cursor moreResults = db.rawQuery("SELECT * FROM " + TableName.MORE_ITEMS.getName(), null);
    List<MoreItems> moreItems = parser.cursorToListOfMoreItems(moreResults);

    items = parser.combineListOfItemsWithListOfMoreItems(items, moreItems);

    db.close();
    result.close();

    return items;
}


This is the cursorToListOfItems() methods that pulls the data out of the cursor and puts it into an ArrayList:

List<Items> cursorToListOfItems(Cursor data) {
    List<Items> items = new ArrayList<Items>();
    Items item = null;

    if (data.moveToFirst()) {
        do {
            item = new Items(DataFactory.getDatabaseItemsData(data));
            items.add(trip);
        }
        while (data.moveToNext());
    }

    return items;
}



Now my problem is that in cursorToListOfItems() the call to moveToNext() always returns true which causes my app to crash.

Thing I Have Tried

  1. I have tried different ways of iterating through the cursor with no change.

  2. I also deleted the app files and uninstalled then reinstalled the app and I still have the same problem.

  3. I also connected the debugger to take a look into the cursor and I can see the marker indicating which row its at go from 0 to 1 indicating that it successfully went to the first row and then the second. But after that every time the loop executes the position stays at 1. indicating that it never goes past the second row to find out if there is any more data to execute and just returns true which starts the infinite loop.

I've now run into a brick wall on this. Any help, answers or suggestions that lead me to a solution are greatly appreciated.

EDIT
I have checked the logs and there are no exceptions thrown. Only logs about the ANR I eventually get. But I will post the logs here just to be safe:

07-15 16:00:02.368 60-309/system_process I/ActivityManager: Starting: Intent { cmp=com.eyephonegrourp.itruckit/.MainActivity } from pid 441
07-15 16:00:02.518 441-441/com.eyephonegrourp.itruckit D/dalvikvm: GC_EXTERNAL_ALLOC freed 27K, 52% free 2589K/5379K, external 3399K/3716K, paused 34ms
07-15 16:00:04.007 441-443/com.eyephonegrourp.itruckit D/dalvikvm: GC_CONCURRENT freed 701K, 50% free 3421K/6727K, external 3842K/4311K, paused 3ms+3ms
07-15 16:00:05.127 441-443/com.eyephonegrourp.itruckit D/dalvikvm: GC_CONCURRENT freed 698K, 44% free 4285K/7623K, external 3842K/4311K, paused 3ms+4ms
07-15 16:00:06.448 441-443/com.eyephonegrourp.itruckit D/dalvikvm: GC_CONCURRENT freed 866K, 40% free 5298K/8775K, external 3842K/4311K, paused 3ms+4ms
07-15 16:00:07.468 60-90/system_process I/InputDispatcher: Application is not responding: Window{406fa4b8 com.eyephonegrourp.itruckit/com.eyephonegrourp.itruckit.SplashActivity paused=true}. 5005.0ms since event, 5004.8ms since wait started
07-15 16:00:07.468 60-90/system_process I/WindowManager: Input event dispatching timed out sending to com.eyephonegrourp.itruckit/com.eyephonegrourp.itruckit.SplashActivity
07-15 16:00:07.503 441-444/com.eyephonegrourp.itruckit I/dalvikvm: threadid=4: reacting to signal 3
07-15 16:00:07.557 441-444/com.eyephonegrourp.itruckit I/dalvikvm: Wrote stack traces to '/data/anr/traces.txt'
07-15 16:00:08.498 441-443/com.eyephonegrourp.itruckit D/dalvikvm: GC_CONCURRENT freed 940K, 36% free 6405K/9991K, external 3842K/4311K, paused 3ms+5ms
07-15 16:00:08.577 60-90/system_process E/ActivityManager: ANR in com.eyephonegrourp.itruckit (com.eyephonegrourp.itruckit/.MainActivity)
Reason: keyDispatchingTimedOut
Parent: com.eyephonegrourp.itruckit/.SplashActivity
Load: 0.36 / 0.27 / 0.14
CPU usage from 47129ms to 2463ms ago:
4% 60/system_server: 3.7% user + 0.2% kernel / faults: 1142 minor
1.6% 349/com.android.launcher: 1.3% user + 0.3% kernel / faults: 3315 minor
0% 40/adbd: 0% user + 0% kernel / faults: 13 minor
0% 135/com.android.systemui: 0% user + 0% kernel / faults: 4 minor
+0% 439/sh: 0% user + 0% kernel
+0% 440/logcat: 0% user + 0% kernel
+0% 441/com.eyephonegrourp.itruckit: 0% user + 0% kernel
13% TOTAL: 11% user + 1.8% kernel
CPU usage from 542ms to 1077ms later:
92% 441/com.eyephonegrourp.itruckit: 92% user + 0% kernel / faults: 207 minor
71% 441/grourp.itruckit: 71% user + 0% kernel
20% 443/GC: 20% user + 0% kernel
5.5% 60/system_server: 1.8% user + 3.7% kernel / faults: 1 minor
3.7% 90/InputDispatcher: 1.8% user + 1.8% kernel
1.8% 61/HeapWorker: 0% user + 1.8% kernel
1.8% 73/ActivityManager: 1.8% user + 0% kernel
98% TOTAL: 92% user + 5.5% kernel
07-15 16:00:10.187 60-73/system_process W/ActivityManager: Force finishing activity com.eyephonegrourp.itruckit/.MainActivity
07-15 16:00:10.208 60-73/system_process I/ActivityManager: Killing com.eyephonegrourp.itruckit (pid=441): user's request
07-15 16:00:10.228 60-126/system_process I/ActivityManager: Process com.eyephonegrourp.itruckit (pid 441) has died.
07-15 16:00:10.238 60-90/system_process E/InputDispatcher: channel '406fa4b8 com.eyephonegrourp.itruckit/com.eyephonegrourp.itruckit.SplashActivity (server)' ~ Consumer closed input channel or an error occurred. events=0x8
07-15 16:00:10.238 60-90/system_process E/InputDispatcher: channel '406fa4b8 com.eyephonegrourp.itruckit/com.eyephonegrourp.itruckit.SplashActivity (server)' ~ Channel is unrecoverably broken and will be disposed!
07-15 16:00:10.268 60-307/system_process I/WindowManager: WIN DEATH: Window{406fa4b8 com.eyephonegrourp.itruckit/com.eyephonegrourp.itruckit.SplashActivity paused=true}


EDIT 2 Here is your requested logs:

07-15 16:13:19.738 1710-6219/system_process I/ActivityManager: Starting activity: Intent { cmp=com.eyephonegrourp.itruckit/.MainActivity } from pid 9583
07-15 16:13:19.908 9583-9583/com.eyephonegrourp.itruckit D/Database: dbopen(): path = /data/data/com.eyephonegrourp.itruckit/databases/itruckit, flag = 6, file size = 11264
07-15 16:13:19.908 9583-9583/com.eyephonegrourp.itruckit D/Database: dbopen(): path = /data/data/com.eyephonegrourp.itruckit/databases/itruckit, mode: wal, disk free size: 2538 M, handle: 0x3496e8
07-15 16:13:23.552 9583-9583/com.eyephonegrourp.itruckit I/log-count: 2
07-15 16:13:23.562 9583-9583/com.eyephonegrourp.itruckit I/log-position: 0
07-15 16:13:23.602 9583-9583/com.eyephonegrourp.itruckit I/log-count: 2
07-15 16:13:23.602 9583-9583/com.eyephonegrourp.itruckit I/log-position: 1
07-15 16:13:23.622 9583-9583/com.eyephonegrourp.itruckit I/log-count: 2
07-15 16:13:23.622 9583-9583/com.eyephonegrourp.itruckit I/log-position: 1
07-15 16:13:23.622 9583-9583/com.eyephonegrourp.itruckit I/log-count: 2
07-15 16:13:23.622 9583-9583/com.eyephonegrourp.itruckit I/log-position: 1
07-15 16:13:23.622 9583-9583/com.eyephonegrourp.itruckit I/log-count: 2
07-15 16:13:23.622 9583-9583/com.eyephonegrourp.itruckit I/log-position: 1
07-15 16:13:23.622 9583-9583/com.eyephonegrourp.itruckit I/log-count: 2
07-15 16:13:23.622 9583-9583/com.eyephonegrourp.itruckit I/log-position: 1
07-15 16:13:23.632 9583-9583/com.eyephonegrourp.itruckit I/log-count: 2
...keeps repeating...


EDIT 3
Here is the code for DataFactory.getDatabaseItemsData(data):

public static final DatabaseHelper.DatabaseTripData getDatabaseTripData(Cursor cursor) {
    if (cursor.moveToFirst()) {
        return createTripData(cursor.getLong(0), cursor.getInt(1), cursor.getInt(2),  
            cursor.getInt(3), cursor.getInt(4), cursor.getString(5), 
            cursor.getString(6), cursor.getLong(7), cursor.getLong(8), 
            cursor.getString(9), cursor.getString(10), cursor.getString(11));
}

return null;
}


And all createTripData() does is take the data from the cursor and creates a wrapper class to hold it.


Solution

  • Your problem is that getDatabaseItemsData calls moveToFirst again.

    You should change getDatabaseItemsData so that it assumes that the cursor is already positioned on a valid record, i.e., just remove the moveToFirst call.