SQLiteBlobTooBigException: Row too big to fit into CursorWindow requiredPos=0, totalRows=1
Asked Answered
Q

5

29

I am getting below exception only in android 9, after reinstalling everything looks good,

Exception:

android.database.sqlite.SQLiteBlobTooBigException: Row too big to fit into CursorWindow requiredPos=0, totalRows=1...

Code:

Cursor cursor = database.query(......);
    if(cursor == null || cursor.getCount() < 0) { //Here is the error
        Log.d("Error", "count : null");
        return "";
    }

Edited:

java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:354)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383)
at java.util.concurrent.FutureTask.setException(FutureTask.java:252)
at java.util.concurrent.FutureTask.run(FutureTask.java:271)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:764)

Caused by: android.database.sqlite.SQLiteBlobTooBigException: Row too big to fit into CursorWindow requiredPos=0, totalRows=1
at android.database.sqlite.SQLiteConnection.nativeExecuteForCursorWindow(Native Method)
at android.database.sqlite.SQLiteConnection.executeForCursorWindow(SQLiteConnection.java:859)
at android.database.sqlite.SQLiteSession.executeForCursorWindow(SQLiteSession.java:836)
at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:62)
at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:149)
at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:137)

Thanks in advance guys

Quadrat answered 22/8, 2018 at 4:35 Comment(6)
Can you edit your question to show the full stack trace, rather than just a single line from the stack trace. Adding the query may also be useful.Olmos
i have edited my ans,check once, @OlmosQuadrat
did you find the solution?? I'm getting the same exception @Bikash Sahani.Pectize
this is happening when ever, some one is upgrading to Oreo without uninstalling my app and keep continue using it, then this problem is coming, so at that time i am dropping the table and creating it againQuadrat
did you got any solution??? I get this problem only in android 9 pocof1 device? after upgrading to the pie in the first-time install I'm getting this error. after i reinstall its working fineEvolutionary
Is there any solution?Disarmament
B
26

This worked for me, you have to put it on your Main Activity.

try {
    Field field = CursorWindow.class.getDeclaredField("sCursorWindowSize");
    field.setAccessible(true);
    field.set(null, 100 * 1024 * 1024); //the 100MB is the new size
    } catch (Exception e) {
       e.printStackTrace();
    }
Briquette answered 15/2, 2021 at 21:32 Comment(1)
This absolutely solved the problem, so thank you and +1. Quick follow-up question, does anyone know if this could trigger any cascaded external Runtime exceptions? IE, if a user has <100mb of free space on their device, will this throw an exception? Or work fine as it is in RAM?Billi
B
4

Try this new constructor method above API 28. Maybe you should set a limited windowSizeBytes for CursorWindow and try-catch the exception.

Related cts code (https://android.googlesource.com/platform/cts/+/master/tests/tests/database/src/android/database/sqlite/cts/SQLiteCursorTest.java) :

    public void testRowTooBig() {
        mDatabase.execSQL("CREATE TABLE Tst (Txt BLOB NOT NULL);");
        byte[] testArr = new byte[10000];
        Arrays.fill(testArr, (byte) 1);
        for (int i = 0; i < 10; i++) {
            mDatabase.execSQL("INSERT INTO Tst VALUES (?)", new Object[]{testArr});
        }
        // Now reduce window size, so that no rows can fit
        Cursor cursor = mDatabase.rawQuery("SELECT * FROM TST", null);
        CursorWindow cw = new CursorWindow("test", 5000);
        AbstractWindowedCursor ac = (AbstractWindowedCursor) cursor;
        ac.setWindow(cw);
        try {
            ac.moveToNext();
            fail("Exception is expected when row exceeds CursorWindow size");
        } catch (SQLiteBlobTooBigException expected) {
        }
    }

Others:

Since this article was originally published, we’ve added new APIs in the Android P developer preview to improve the behavior above. The platform now allows apps to disable the ⅓ of a window heuristic and configure CursorWindow size.

Ref Link: https://medium.com/androiddevelopers/large-database-queries-on-android-cb043ae626e8

Bicameral answered 24/4, 2019 at 10:48 Comment(0)
H
0

I found how to use length() and substr() to request only 1MB (the max for CursorWindow is 2MB), maybe it will help. Also, you could use context.getContentResolver().query() with a selection that only includes the _id column, that way you won't load data related to the other columns.

Helix answered 15/12, 2019 at 23:11 Comment(0)
P
0

Try to scale bitmap:

Bitmap.createScaledBitmap
Puccini answered 25/3, 2020 at 7:13 Comment(0)
B
0

Try using this code in the onCreate function of MainApplication. It worked for me.

import android.database.CursorWindow;
import java.lang.reflect.Field;

@Override public void onCreate() {
super.onCreate();
try {
  @SuppressLint("PrivateApi") 
  Field field = 
  CursorWindow.class.getDeclaredField("sCursorWindowSize");
  field.setAccessible(true);
  field.set(null, 100 * 1024 * 1024); //the 100MB is the new size
} catch (Exception e) {
    e.printStackTrace();
}
Burka answered 26/12, 2023 at 2:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.