Search code examples
androidandroid-sqliteandroid-cursoradapterandroid-cursorandroid-cursorloader

Odd Cursor Behavior


I'm currently developing an Application that uses a Database / ContentProvider to provide certain location data that's pulled from the network and stored locally in a database periodically.

I've verified that the database is created correctly in the Application, and the Tables are populated with data by exporting a copy of the app local database to the SD card for viewing in a SQL browser -- so the data not being present is not the issue here.

The odd behavior is probably better visualized through a couple of screen shots of my debugging process:

So, initially when I did my queries, all of my Cursor objects were returning -1 for the row count, even though I verified that a SELECT * FROM TABLE_NAME statement should return values, since the database I pulled off of the device contains row data. Here's a look at the debugger step:

enter image description here

Notice that when the cursor is initially returned, mCount displays as -1.

Out of curiosity, I added the cursor.moveToFirst(); call, and here's a screenshot from after that step:

enter image description here

Notice that the cursor count changed from -1 to 3, which corresponds to the correct number of rows (since the application only accounts for 3 continents atm). Unfortunately, this added line that should be unnecessary still doesn't fix my problem, since CursorAdapter.bindView() and CursorAdapter.newView() still fail to be called with the resulting cursor.

I'm confused as to what could be causing this issue, and how to fix it? If anyone could give any insight into what the problem could be, please let me know. Also, if any additional code is needed, such as the SQL create statements, etc let me know - however, as I've already mentioned the database is created fine and queries performed on the exported db copy outside of the Android application work just fine...

One last thing, the application is built for API levels 14+.


Solution

  • If you have an SQL query that are reading from the database you would want to delay reading that data until you are certain that you will use it.

    So when you call rawQuery you get a reference to a Cursor object. But nothing is read yet. This is what themoveToFirst does. It is the first thing that tells the cursor that you are serious about running this SQL query and that you want a result.

    But since you are using rawQuery nothing is passed on to the database before you try to fetch a result with moveToFirst.

    Hope this answers your question.