Search code examples
javaandroiddatabasesqliteandroid-sqlite

App crashes after accessing data from SQLite Database android


In my code, I am creating a SQLite database and a table, and adding the data into the table, this part is working fine. But the problem arises when I'm accessing the data. It retrieves the stored data and at the end crashes the app. Does the while loop cause this?

Here's my code:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //creating  a new Or accessing an existing database
        SQLiteDatabase myDatabase = this.openOrCreateDatabase("Users",MODE_PRIVATE,null);

        //creating a table if it does not exist
        myDatabase.execSQL("CREATE TABLE IF NOT EXISTS users(name VARCHAR,age INT(3))");

        //inserting data into the users table
        //single row of values
        myDatabase.execSQL("INSERT INTO users(name,age) VALUES('Robert',28)");
        //multiple rows of values
        myDatabase.execSQL("INSERT INTO users(name,age) VALUES('Derek',30), ('Israel',31), ('Jared',24)");

        //accessing data and traversing across table users
        Cursor c = myDatabase.rawQuery("SELECT * FROM users",null);

        int nameIndex = c.getColumnIndex("name");   //setting index  for name column
        int ageIndex = c.getColumnIndex("age");     //setting index  for age column

        c.moveToFirst(); //setting the cursor on starting position

//traversing across the table row by row
        while (c != null){
            Log.i("name",c.getString(nameIndex));
            Log.i("age",c.getString(ageIndex));

            c.moveToNext();
        }

    }
} 

Here are the logs:

2020-10-26 13:29:53.199 18545-18545/com.example.databasedemo1 I/name: Robert
2020-10-26 13:29:53.199 18545-18545/com.example.databasedemo1 I/age: 28
2020-10-26 13:29:53.199 18545-18545/com.example.databasedemo1 I/name: Derek
2020-10-26 13:29:53.199 18545-18545/com.example.databasedemo1 I/age: 30
2020-10-26 13:29:53.199 18545-18545/com.example.databasedemo1 I/name: Israel
2020-10-26 13:29:53.199 18545-18545/com.example.databasedemo1 I/age: 31
2020-10-26 13:29:53.199 18545-18545/com.example.databasedemo1 I/name: Jared
2020-10-26 13:29:53.199 18545-18545/com.example.databasedemo1 I/age: 24
2020-10-26 13:29:53.200 18545-18545/com.example.databasedemo1 D/AndroidRuntime: Shutting down VM
2020-10-26 13:29:53.206 18545-18545/com.example.databasedemo1 E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.databasedemo1, PID: 18545
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.databasedemo1/com.example.databasedemo1.MainActivity}: 

android.database.CursorIndexOutOfBoundsException: Index 4 requested, with a size of 4
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2817)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)
        at android.app.ActivityThread.-wrap11(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6541)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
     Caused by: android.database.CursorIndexOutOfBoundsException: Index 4 requested, with a size of 4
        at android.database.AbstractCursor.checkPosition(AbstractCursor.java:460)
        at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:136)
        at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:50)
        at com.example.databasedemo1.MainActivity.onCreate(MainActivity.java:39)
        at android.app.Activity.performCreate(Activity.java:6975)

Solution

  • The way that you loop through the rows of the Cursor is wrong.
    Remove the 1st call to c.moveToFirst(); and use c.moveToNext() to check if there is another row in the Cursor:

    while (c.moveToNext()) {
        Log.i("name",c.getString(nameIndex));
        Log.i("age",c.getString(ageIndex));
    }
    

    This way the loop will stop after the last row is accessed because c.moveToNext() will return false.