android.database.CursorIndexOutOfBoundsException ...再次android、database、CursorIndexOutOfBoundsExcepti

2023-09-06 10:34:55 作者:嫑忈嘦怹.

所以,我在用户崩溃报告这个错误我的应用程序。以下是报告:

  android.database.CursorIndexOutOfBoundsException:索引0要求,大小为0在android.database.AbstractCursor.checkPosition(AbstractCursor。)在android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor。)在android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:50)在rs.androidaplikacije.zastaveigradovi.Kviz10Hard.nextQuestionGrad(Kviz10Hard。)在rs.androidaplikacije.zastaveigradovi.Kviz10Hard.access $ 1(Kviz10Hard。)在rs.androidaplikacije.zastaveigradovi.Kviz10Hard $ 2.run(Kviz10Hard.java:68)在android.os.Handler.handleCallback(处理器)。在android.os.Handler.dispatchMessage(Handler.java:92)在android.os.Looper.loop(活套)。在android.app.ActivityThread.main(ActivityThread。)在java.lang.reflect.Method.invokeNative(本机方法)在java.lang.reflect.Method.invoke(方法)。在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit。)在com.android.internal.os.ZygoteInit.main(ZygoteInit。)在dalvik.system.NativeStart.main(本机方法) 

而这里提到的code:

 私人无效nextQuestionGrad(){    flag.setVisibility(View.GONE);    dodatnoPitanje.setVisibility(View.VISIBLE);    TestAdapter mDbHelper =新TestAdapter(本);    DataBaseHelper myDbHelper =新DataBaseHelper(本);    如果(!myDbHelper.checkDataBase()){        mDbHelper.createDatabase();    }    尝试{        mDbHelper.open();        光标C = mDbHelper.getTestDataGradovi(mCurrentID);        清单<应答和GT;标签=新的ArrayList<应答和GT;();        labels.add(新答(c.getString(2),真));        labels.add(新答(c.getString(3),FALSE));        labels.add(新答(c.getString(4),FALSE));        labels.add(新答(c.getString(5),FALSE));        tacanOdg = c.getString(2);        Collections.shuffle(标签);        dodatnoPitanje.setText(c.getString(1));        bOdgovor1.setText(labels.get(0)。选项);        bOdgovor1.setTag(labels.get(0));        bOdgovor1.setOnClickListener(clickListenerGrad);        bOdgovor2.setText(labels.get(1)。选项);        bOdgovor2.setTag(labels.get(1));        bOdgovor2.setOnClickListener(clickListenerGrad);        bOdgovor3.setText(labels.get(2)。选项);        bOdgovor3.setTag(labels.get(2));        bOdgovor3.setOnClickListener(clickListenerGrad);        bOdgovor4.setText(labels.get(3)。选项);        bOdgovor4.setTag(labels.get(3));        bOdgovor4.setOnClickListener(clickListenerGrad);        score.setText(分数:+ brojacTacnihOdgovora);    }最后{        mDbHelper.close();    }} 

和我使用这个类我的适配器类的一部分:

 公共光标getTestDataGradovi(长ID){    尝试{        SQL字符串=SELECT * FROM tblGradovi WHERE _ID =+ ID;        光标C = mDb.rawQuery(SQL,NULL);        如果(C!= NULL){            c.moveToNext();        }        返回℃;    }赶上(的SQLException mSQLException){        Log.e(TAGgetTestData>>中+ mSQLException.toString());        扔mSQLException;    } } 
Android 开发中使用 SQLite 数据库

有人能告诉我在哪里的问题?错误行(Kviz10Hard)是在这里:

  labels.add(新答(c.getString(2),真)); 

解决方案

试图从光标得到任何数据之前对象,你需要遍历结果或得到第一个一个,如果所述光标仅包含一个值。例如所有的结果之间的循环,你应该做这样的事情:

 字符串SQL =SELECT * FROM myTable的;光标光标= mDbHelper.rawQuery(SQL,NULL);如果(指针!= NULL){    如果(cursor.getCount()大于0){        为(cursor.move(0); cursor.moveToNext(); cursor.isAfterLast()){            //获取你的数据在这里        }    }    cursor.close(); //关闭你的光标,当你不需要它了} 

或另一种方式来做到这一点:

 字符串SQL =SELECT * FROM myTable的;光标光标= mDbHelper.rawQuery(SQL,NULL);如果(指针!= NULL){    如果(cursor.getCount()大于0){        做{             //获得价值        }而(cursor.moveToNext());    }    cursor.close(); //关闭你的光标,当你不需要它了} 

或者如果你是pretty确保结果应该是取决于你的SQL语句,你应该叫 cursor.moveToFirst()只有一个对象; 访问任何东西之前从光标是这样的:

 字符串SQL =SELECT * FROM myTable的;光标光标= mDbHelper.rawQuery(SQL,NULL);如果(指针!= NULL){    cursor.moveToFirst();    字符串的myString = cursor.getString(cursor.getColumnIndex(标题));    cursor.close(); //关闭你的光标,当你不需要它了} 

编辑:

如果你真的想在你的数据库类来创建这样的功能,我会做这样的事情:

 公共静态光标getUserTitles(INT用户id){      SQL字符串=SELECT * FROM myTable的其中userid =?;      返回mDbHelper.rawQuery(SQL,新的String [] {Integer.toString(用户ID)});} 

第二个编辑:

更改 getTestDataGradovi 来:

 公共光标getTestDataGradovi(长ID){    SQL字符串=SELECT * FROM tblGradovi WHERE _ID =?;    返回mDb.rawQuery(SQL,新的String [] {Integer.toString(ID)});} 

和增加 c.moveToFirst(); ,在光标C = mDbHelper.getTestDataGradovi(mCurrentID);

So, I have this error in user crash report for my app. Here's the report:

android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
at android.database.AbstractCursor.checkPosition(AbstractCursor.)
at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.)
at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:50)
at rs.androidaplikacije.zastaveigradovi.Kviz10Hard.nextQuestionGrad(Kviz10Hard.)
at rs.androidaplikacije.zastaveigradovi.Kviz10Hard.access$1(Kviz10Hard.)
at rs.androidaplikacije.zastaveigradovi.Kviz10Hard$2.run(Kviz10Hard.java:68)
at android.os.Handler.handleCallback(Handler.)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.)
at android.app.ActivityThread.main(ActivityThread.)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.)
at dalvik.system.NativeStart.main(Native Method)

And here's the mentioned code:

private void nextQuestionGrad() {

    flag.setVisibility(View.GONE);
    dodatnoPitanje.setVisibility(View.VISIBLE);

    TestAdapter mDbHelper = new TestAdapter(this);
    DataBaseHelper myDbHelper = new DataBaseHelper(this);

    if(!myDbHelper.checkDataBase()){
        mDbHelper.createDatabase();
    }

    try{ 

        mDbHelper.open();

        Cursor c = mDbHelper.getTestDataGradovi(mCurrentID);

        List<Answer> labels = new ArrayList<Answer>();

        labels.add(new Answer(c.getString(2), true));
        labels.add(new Answer(c.getString(3), false));
        labels.add(new Answer(c.getString(4), false));
        labels.add(new Answer(c.getString(5), false));

        tacanOdg = c.getString(2);

        Collections.shuffle(labels);

        dodatnoPitanje.setText(c.getString(1));

        bOdgovor1.setText(labels.get(0).option);
        bOdgovor1.setTag(labels.get(0));
        bOdgovor1.setOnClickListener(clickListenerGrad);

        bOdgovor2.setText(labels.get(1).option);
        bOdgovor2.setTag(labels.get(1));
        bOdgovor2.setOnClickListener(clickListenerGrad);

        bOdgovor3.setText(labels.get(2).option);
        bOdgovor3.setTag(labels.get(2));
        bOdgovor3.setOnClickListener(clickListenerGrad);

        bOdgovor4.setText(labels.get(3).option);
        bOdgovor4.setTag(labels.get(3));
        bOdgovor4.setOnClickListener(clickListenerGrad);

        score.setText("Score: " + brojacTacnihOdgovora);

    }finally{ 
        mDbHelper.close();
    }
}

And part of my adapter class I'm using for this class:

public Cursor getTestDataGradovi(long id){
    try{
        String sql ="SELECT * FROM tblGradovi WHERE _ID = " + id;

        Cursor c = mDb.rawQuery(sql, null);
        if (c!=null){
            c.moveToNext();
        }
        return c;
    }catch (SQLException mSQLException){
        Log.e(TAG, "getTestData >>"+ mSQLException.toString());
        throw mSQLException;
    }
 }

Can someone tell me where's the problem? The error line (Kviz10Hard.) is here:

labels.add(new Answer(c.getString(2), true));

解决方案

Before trying to get any data from a Cursor object you need to iterate the result or get the first one if the cursor contains only one value. For example to iterate between all result you should do something like this :

String sql = "SELECT * FROM myTable";
Cursor cursor = mDbHelper.rawQuery(sql, null);
if(cursor != null){
    if(cursor.getCount() > 0){
        for(cursor.move(0);cursor.moveToNext();cursor.isAfterLast()){
            // get your data here
        }
    }
    cursor.close(); // close your cursor when you don't need it anymore
}

or another way to do this it :

String sql = "SELECT * FROM myTable";
Cursor cursor = mDbHelper.rawQuery(sql, null);
if(cursor != null){
    if(cursor.getCount() > 0){
        do {
             // get value
        } while(cursor.moveToNext());
    }
    cursor.close(); // close your cursor when you don't need it anymore
}

or if you are pretty sure that the result should be only one object depending on your sql statement you should call cursor.moveToFirst(); before accessing anything from your Cursor like this :

String sql = "SELECT * FROM myTable";
Cursor cursor = mDbHelper.rawQuery(sql, null);
if(cursor != null){
    cursor.moveToFirst();
    String myString = cursor.getString(cursor.getColumnIndex("title"));
    cursor.close(); // close your cursor when you don't need it anymore
}

Edit:

If you really want to create function like this in your database class I would do something like this :

public static Cursor getUserTitles(int userId){
      String sql = "SELECT * FROM myTable WHERE userId=?";
      return mDbHelper.rawQuery(sql, new String[]{Integer.toString(userId)});
}

Second Edit:

Change your getTestDataGradovi to :

public Cursor getTestDataGradovi(long id){
    String sql ="SELECT * FROM tblGradovi WHERE _ID=?";
    return  mDb.rawQuery(sql, new String[]{Integer.toString(id)});
}

and add c.moveToFirst(); , after Cursor c = mDbHelper.getTestDataGradovi(mCurrentID);