Reading Sqlite Cursor carsh on Android 4.2 API 17

2020-05-10 09:18发布

I have a table with 145 rows. when i try to get all of it's data it getting crashed on android 4.2, BUT it works fine on android 4.4 emulator.

public ArrayList<QuestionInfoHolder> getAllArticle()
    {
        ArrayList<QuestionInfoHolder> result = new ArrayList<QuestionInfoHolder>();
        SQLiteDatabase db = getReadableDatabase();
        String query = "SELECT * FROM " + ARTICLE_TABLE_NAME + " ORDER BY "+ QUESTION_DATE +";";
        Cursor cursor = db.rawQuery(query, null);
        if(cursor != null)
        {
            for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext())
            {
                result.add(new QuestionInfoHolder(cursor.getInt(0),
                        cursor.getInt(1),
                        cursor.getString(2),
                        cursor.getString(3),
                        cursor.getString(4)));
            }
        }

        return result;
    }

the logcat:

Failed to read row 9, column 0 from a CursorWindow which has 9 rows, 5 columns.
FATAL EXCEPTION: main
java.lang.IllegalStateException: Couldn't read row 9, col 0 from CursorWindow.  Make sure the Cursor is initialized correctly before accessing data from it.

this says the cursor has only 9 rows, but if i log cursor.getCount(); it will show 145.

i can not figure out what is the problem. so any help or suggestion will be appreciated.

UPDATE 1:

DatabaseUtils.dumpCursor(cursor); log:

I/System.out: 99 {
E/CursorWindow: Failed to read row 9, column 0 from a CursorWindow which has 9 rows, 5 columns.
D/AndroidRuntime: Shutting down VM
W/dalvikvm: threadid=1: thread exiting with uncaught exception (group=0x41b5e9a8)
E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.IllegalStateException: Couldn't read row 9, col 0 from CursorWindow.  Make sure the Cursor is initialized correctly before accessing data from it.
at android.database.CursorWindow.nativeGetString(Native Method)
at android.database.CursorWindow.getString(CursorWindow.java:434)
at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:51)
at android.database.DatabaseUtils.dumpCurrentRow(DatabaseUtils.java:562)
at android.database.DatabaseUtils.dumpCursor(DatabaseUtils.java:499)
at android.database.DatabaseUtils.dumpCursor(DatabaseUtils.java:482)

3条回答
干净又极端
2楼-- · 2020-05-10 09:33

Read The Cursor in this way

   if (cursor.moveToFirst()) {
            do {

              result.add(new QuestionInfoHolder(cursor.getInt(0),
                    cursor.getInt(1),
                    cursor.getString(2),
                    cursor.getString(3),
                    cursor.getString(4)));

            }
            while (cursor.moveToNext());

        }
查看更多
够拽才男人
3楼-- · 2020-05-10 09:46

with the help from @pskink i finally reached this code that can retrieve all data without any error. tnx everybody.

ArrayList<QuestionInfoHolder> result = new ArrayList<QuestionInfoHolder>();
        SQLiteDatabase db = getReadableDatabase();
        android.database.sqlite.SQLiteStatement st = db.compileStatement("SELECT Content FROM " + ARTICLES_TABLE_NAME + " WHERE ID = ?;");
        String query = "SELECT ID,CategoryID,Title,Date FROM " + ARTICLES_TABLE_NAME +";";
        Cursor cursor = db.rawQuery(query, null);
        if(cursor != null)
        {
            for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext())
            {
                st.bindLong(1, cursor.getInt(0));
                String content = st.simpleQueryForString();
                result.add(new QuestionInfoHolder(cursor.getInt(0),
                        cursor.getInt(1),
                        cursor.getString(2),
                        cursor.getString(3),
                        content));
            }
        }
查看更多
Rolldiameter
4楼-- · 2020-05-10 09:47

Underlying Android CursorWindow is limited to 2MB of data. Attempting to work with a Cursor that has more data than that will cause these "failed to read" exceptions.

You can work around it by not including columns with large data in your query. Replace the SELECT * with a more selective SELECT column1,column2,... without any large data columns.

Overall you should not store any large data such as images or file content in an Android sqlite database. Store the large data in the filesystem and just store the path in your database.

查看更多
登录 后发表回答