当前位置: 首页 > 知识库问答 >
问题:

从Android数据库中删除项目-游标索引越界异常

班安平
2023-03-14

在我的android应用程序中,我试图从数据库中删除一个项目,已经在列表视图中选择了相应的项目,并从长按时创建的上下文菜单中选择了一个项目。listview是从arraylist填充的,而arraylist是从数据库中的项创建的。

然而,当我试图删除listview中的第一个项目以外的任何项目时,我会遇到一个错误(这实际上是最近添加的项目,也是arraylist中的最后一个项目,因为listview以相反的顺序显示列表中的项目)。如果我尝试删除一个项目而不是最新的项目,那么我会得到一个错误,android.database.cursorIndexOutOfBoundsException:requested索引0,大小为0。

在这个错误之后,如果我试图打开包含listview的activity,我也会得到同样的错误,直到我删除应用程序的数据并再次打开它。

如果光标是空的并且它正在移动到下一行,我尝试签入databasehandler deleteGoalFromDb方法,但是到目前为止没有成功

在上下文菜单中按下delete项时调用的方法(它是菜单中唯一的项):

@Override
    public boolean onContextItemSelected(MenuItem item) { //what to do when menu item clicked in context menu
        AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
        //call delete goal and make it delete goal
        //System.out.println(info.position+"****************");
        int position_actual = goalsList.size() - info.position; //needed as list is displayed in reverse order
        //System.out.println(position_actual+"----------------------");
        deleteGoal(position_actual);
        return true;
    }

我的deleteGoal()方法:

public void deleteGoal(int id) {
        db.deleteGoalFromDb(id); //deletes the goal from the database
        makeGoalsFromDB(); //refreshes the goalsList
    }

DeleteGoalFromDB:

public void deleteGoalFromDb(int id){
        SQLiteDatabase db = this.getWritableDatabase();
        db.delete(TABLE_GOALS, KEY_ID + " = ?", new String[] {id+""});
        db.close();
    }

MakeGoalsFromDB:

public void makeGoalsFromDB() {
        //looping through the table, get the goals and add them to the goals list
        goalsList = new ArrayList<Goal>(); 
        int goalsNo = db.getGoalsCount();
        for (int i = 1; i <= goalsNo; i++) { 
            goalsList.add(db.readGoalFromDb(i));
        }
    }

ReadGoalFromDB:

public Goal readGoalFromDb(int id) { //method to get a goal from the database
        SQLiteDatabase db = this.getWritableDatabase();

        Cursor cursor = db.query(TABLE_GOALS, new String[] { KEY_ID,
                KEY_STROKE, KEY_TIME_HRS, KEY_TIME_MIN, KEY_TIME_SECS, KEY_DISTANCE, KEY_ACHIEVED, KEY_DATE_GOAL }, KEY_ID + "=?",
                new String[] { String.valueOf(id) }, null, null, null, null);
        if (cursor != null)
            cursor.moveToFirst();

        Goal goal = new Goal(cursor.getInt(0), cursor.getString(1), cursor.getInt(2),
                cursor.getInt(3), cursor.getInt(4),
                cursor.getInt(5), Boolean.parseBoolean(cursor.getString(6)), cursor.getString(7));

        cursor.close();
        db.close();
        return goal;

    }

目标是用(int,String,int,int,int,int,int,boolean,String)创建的。

下面是我对错误的logcat:

08-24 12:29:37.850: E/AndroidRuntime(7897): FATAL EXCEPTION: main
08-24 12:29:37.850: E/AndroidRuntime(7897): Process: com.lyncht.swimtracker, PID: 7897
08-24 12:29:37.850: E/AndroidRuntime(7897): android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
08-24 12:29:37.850: E/AndroidRuntime(7897):     at android.database.AbstractCursor.checkPosition(AbstractCursor.java:426)
08-24 12:29:37.850: E/AndroidRuntime(7897):     at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:136)
08-24 12:29:37.850: E/AndroidRuntime(7897):     at android.database.AbstractWindowedCursor.getInt(AbstractWindowedCursor.java:68)
08-24 12:29:37.850: E/AndroidRuntime(7897):     at com.lyncht.swimtracker.DatabaseHandler.readGoalFromDb(DatabaseHandler.java:128)
08-24 12:29:37.850: E/AndroidRuntime(7897):     at com.lyncht.swimtracker.ViewGoals.makeGoalsFromDB(ViewGoals.java:76)
08-24 12:29:37.850: E/AndroidRuntime(7897):     at com.lyncht.swimtracker.ViewGoals.deleteGoal(ViewGoals.java:68)
08-24 12:29:37.850: E/AndroidRuntime(7897):     at com.lyncht.swimtracker.ViewGoals.onContextItemSelected(ViewGoals.java:61)
08-24 12:29:37.850: E/AndroidRuntime(7897):     at android.app.Activity.onMenuItemSelected(Activity.java:2620)
08-24 12:29:37.850: E/AndroidRuntime(7897):     at com.android.internal.policy.impl.PhoneWindow$DialogMenuCallback.onMenuItemSelected(PhoneWindow.java:3864)
08-24 12:29:37.850: E/AndroidRuntime(7897):     at com.android.internal.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:741)
08-24 12:29:37.850: E/AndroidRuntime(7897):     at com.android.internal.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:152)
08-24 12:29:37.850: E/AndroidRuntime(7897):     at com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:884)
08-24 12:29:37.850: E/AndroidRuntime(7897):     at com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:874)
08-24 12:29:37.850: E/AndroidRuntime(7897):     at com.android.internal.view.menu.MenuDialogHelper.onClick(MenuDialogHelper.java:167)
08-24 12:29:37.850: E/AndroidRuntime(7897):     at com.android.internal.app.AlertController$AlertParams$3.onItemClick(AlertController.java:941)
08-24 12:29:37.850: E/AndroidRuntime(7897):     at android.widget.AdapterView.performItemClick(AdapterView.java:299)
08-24 12:29:37.850: E/AndroidRuntime(7897):     at android.widget.AbsListView.performItemClick(AbsListView.java:1113)
08-24 12:29:37.850: E/AndroidRuntime(7897):     at android.widget.AbsListView$PerformClick.run(AbsListView.java:2911)
08-24 12:29:37.850: E/AndroidRuntime(7897):     at android.widget.AbsListView$3.run(AbsListView.java:3645)
08-24 12:29:37.850: E/AndroidRuntime(7897):     at android.os.Handler.handleCallback(Handler.java:733)
08-24 12:29:37.850: E/AndroidRuntime(7897):     at android.os.Handler.dispatchMessage(Handler.java:95)
08-24 12:29:37.850: E/AndroidRuntime(7897):     at android.os.Looper.loop(Looper.java:136)
08-24 12:29:37.850: E/AndroidRuntime(7897):     at android.app.ActivityThread.main(ActivityThread.java:5001)
08-24 12:29:37.850: E/AndroidRuntime(7897):     at java.lang.reflect.Method.invokeNative(Native Method)
08-24 12:29:37.850: E/AndroidRuntime(7897):     at java.lang.reflect.Method.invoke(Method.java:515)
08-24 12:29:37.850: E/AndroidRuntime(7897):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
08-24 12:29:37.850: E/AndroidRuntime(7897):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
08-24 12:29:37.850: E/AndroidRuntime(7897):     at dalvik.system.NativeStart.main(Native Method)

共有2个答案

云曦之
2023-03-14

readgoalfromdb(int id)

 Goal goal = null;
 if (cursor != null)
       if(cursor.moveToFirst()) // IMPORTANT!, check whether the returned cursor is empty
       {

           goal = new Goal(cursor.getInt(0), cursor.getString(1), cursor.getInt(2),
            cursor.getInt(3), cursor.getInt(4),
            cursor.getInt(5), Boolean.parseBoolean(cursor.getString(6)), cursor.getString(7));
            return goal;
        }
        else {
           //the returned cursor is empty
             Log.v("cursorempty","the cursor was returned empty");
             return null
        }

您检查了null,但没有检查游标是否有项。您只是尝试检索导致CursorIndexOutOfBoundsException的值。

如果返回的游标为空,则采取适当的操作

MakeGoalsFromdb()修改为:

public void makeGoalsFromDB() {
        //looping through the table, get the goals and add them to the goals list
        goalsList = new ArrayList<Goal>(); 
        int goalsNo = db.getGoalsCount();
        for (int i = 1; i <= goalsNo; i++) { 
            if(null != db.readGoalFromDb(i)) 
            goalsList.add(db.readGoalFromDb(i));
        }
    }
柴瀚昂
2023-03-14

就像Frank N.Stein已经说过的:你需要使用你想要删除的目标的数据库id。因此在onContextItemSelected中编写如下内容:

int idToDelete = listView.getItem(position).getGoalId();
deleteGoal(idToDelete);
 类似资料:
  • 这是我的代码: 该程序的目的是要求用户输入一个字符串,然后统计字符串中每个字符的使用次数。 当我去编译程序时,它工作正常。当我运行程序时,我可以在弹出框中输入字符串,但是在我提交字符串并按确定后,我得到一个错误,说 我不完全确定问题是什么或如何解决。

  • 我一直在四处寻找是否有任何东西可以帮助我,但我不太了解人们的回答,任何我所了解的似乎都不能解决问题!所以基本上正如标题所说,我得到了一个数组索引越界异常,但我不知道为什么。非常感谢任何帮助。 代码:

  • 在Java中构建汇编程序:我试图将用户的输入读入名为的。如果用户输入的指令与-array中的一个匹配,那么相应的操作码将被计算出来并输出到一个文本文件中。 但是,在输入指令并尝试添加另一条指令后,我得到了一个索引越界异常。 如果你们能帮忙,我会很感激的。

  • 问题内容: 在我的游戏代码中,我尝试添加一张手牌。一旦我做完了,我的数组就超出了范围。一切看起来都不错,但也许我缺少了一些东西。 仅供参考,一个和两个是Player实例。来自Main类的相关代码(对格式感到抱歉。我很想将其传输到Stack Overflow): 卡类: 玩家等级: 问题答案: 问题出在你的循环上 没有其他任何值可设置,因此此循环不断循环,直到所有玩家拥有超过52张牌为止。一旦某人拥

  • 我正在尝试做一个Java线程,这个线程必须从一个MySQL数据库中删除所有的记录,超过7天。 在我的表中,我有一列包含如下日期:。

  • 这段代码是关于一个水罐车游荡在一个环境中寻找有任务的水站。 试图通过访问点的数组列表进行递增,但每次运行代码时,我都得到一个“indexoutofboundsexception”,但其索引不同,而且大小总是与索引相同,所以我非常困惑。中断程序的索引/大小看起来是随机变化的。 示例错误:线程“main”java.lang.IndexOutOfBoundsException:Index:5,SIZE: