首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >请求索引0,大小为0

请求索引0,大小为0
EN

Stack Overflow用户
提问于 2018-06-06 02:41:28
回答 1查看 150关注 0票数 0

当我尝试从android.database.CursorIndexOutOfBoundsException:数据库中列出数据时,我得到了一个Sqlite索引0请求,大小为0的错误。通过读取具有相同错误的其他问题,我可以断定第一条记录有一个空值。解决方案似乎是关闭光标,但我已经这样做了,所以这不是原因。除非我错误地关闭了光标。我已经发布了我得到的错误和我认为与该错误相关的代码。任何有关如何解决此错误的指导都将不胜感激。

代码语言:javascript
复制
Process: ca.rvogl.tpbcui, PID: 30793
    android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
        at android.database.AbstractCursor.checkPosition(AbstractCursor.java:460)
        at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:136)
        at android.database.AbstractWindowedCursor.getInt(AbstractWindowedCursor.java:68)
        at ca.rvogl.tpbcui.Database.DatabaseHelper.getGame(DatabaseHelper.java:445)
        at ca.rvogl.tpbcui.Views.GameActivity.createGame(GameActivity.java:113)
        at ca.rvogl.tpbcui.Views.GameActivity.access$800(GameActivity.java:30)
        at ca.rvogl.tpbcui.Views.GameActivity$7.onClick(GameActivity.java:244)
        at android.view.View.performClick(View.java:5637)
        at android.view.View$PerformClick.run(View.java:22429)
        at android.os.Handler.handleCallback(Handler.java:751)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:154)
        at android.app.ActivityThread.main(ActivityThread.java:6119)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)

来自我的DatabaseHelper的代码

代码语言:javascript
复制
public Game  getGame(String leagueId, String bowlerId, String seriesId) {
        //Get Readable Database If We Are Not Inserting Anything
        SQLiteDatabase db = this.getReadableDatabase();

        Cursor cursor = db.query( Game.TABLE_NAME,
                new String[]{Game.COLUMN_ID, Game.COLUMN_LEAGUE_ID, Game.COLUMN_BOWLER_ID,
                        Game.COLUMN_SERIES_ID, Game.COLUMN_SCORE, Game.COLUMN_STRIKES, Game.COLUMN_SPARES,Game.COLUMN_SPLITS, Game.COLUMN_SPLIT_CONVERSIONS, Game.COLUMN_OPEN_FRAMES, Game.COLUMN_TIMESTAMP},
                Game.COLUMN_LEAGUE_ID + "=?" + " AND " +  Game.COLUMN_BOWLER_ID + "=?" + " AND " +  Game.COLUMN_SERIES_ID + "=?",
                new String[]{String.valueOf(leagueId), String.valueOf(bowlerId), String.valueOf(seriesId)}, null, null, null, null);

        if (cursor != null)
            cursor.moveToFirst();

        //Prepare Game Object
        Game game = new Game(

                cursor.getInt(cursor.getColumnIndex(Game.COLUMN_ID)),
                cursor.getString(cursor.getColumnIndex(Game.COLUMN_LEAGUE_ID)),
                cursor.getString(cursor.getColumnIndex(Game.COLUMN_BOWLER_ID)),
                cursor.getString(cursor.getColumnIndex(Game.COLUMN_SERIES_ID)),
                cursor.getString(cursor.getColumnIndex(Game.COLUMN_SCORE)),
                cursor.getString(cursor.getColumnIndex(Game.COLUMN_STRIKES)),
                cursor.getString(cursor.getColumnIndex(Game.COLUMN_SPARES)),
                cursor.getString(cursor.getColumnIndex(Game.COLUMN_SPLITS)),
                cursor.getString(cursor.getColumnIndex(Game.COLUMN_SPLIT_CONVERSIONS)),
                cursor.getString(cursor.getColumnIndex(Game.COLUMN_OPEN_FRAMES)),
                cursor.getString(cursor.getColumnIndex(Game.COLUMN_TIMESTAMP)));

        //Close Database Connection
        cursor.close();

        return game;
    }

    public List<Game> getAllGames(String leagueId, String bowlerId, String seriesId) {
        List<Game> games = new ArrayList<>();

        //Select All Query
        String selectQuery = "SELECT  * FROM " + Game.TABLE_NAME + " WHERE " + Game.COLUMN_LEAGUE_ID + " = '" + leagueId + "'" + " AND " + Game.COLUMN_BOWLER_ID + " = '" + bowlerId + "'" + " AND " + Game.COLUMN_SERIES_ID + " = '" + seriesId + "'" + " ORDER BY " +
                Game.COLUMN_TIMESTAMP + " DESC";

        try (SQLiteDatabase db = this.getWritableDatabase()) {
            @SuppressLint("Recycle") Cursor cursor = db.rawQuery( selectQuery, null );

            //Looping Through All Rows And Adding To The List
            if (cursor.moveToFirst()) {
                do {
                    Game game1 = new Game();
                    game1.setId(cursor.getInt(cursor.getColumnIndex(Game.COLUMN_ID ) ) );
                    game1.setLeagueId(cursor.getString(cursor.getColumnIndex(Game.COLUMN_LEAGUE_ID)));
                    game1.setBowlerId(cursor.getString(cursor.getColumnIndex(Game.COLUMN_BOWLER_ID)));
                    game1.setSeriesId(cursor.getString(cursor.getColumnIndex(Game.COLUMN_SERIES_ID)));
                    game1.setScore(cursor.getString(cursor.getColumnIndex(Game.COLUMN_SCORE)));
                    game1.setSpares(cursor.getString(cursor.getColumnIndex(Game.COLUMN_SPARES)));
                    game1.setSplits(cursor.getString(cursor.getColumnIndex(Game.COLUMN_SPLITS)));
                    game1.setSplitConversions(cursor.getString(cursor.getColumnIndex(Game.COLUMN_SPLIT_CONVERSIONS)));
                    game1.setOpenFrames(cursor.getString(cursor.getColumnIndex(Game.COLUMN_OPEN_FRAMES)));
                    game1.setTimestamp(cursor.getString(cursor.getColumnIndex(Game.COLUMN_TIMESTAMP)));

                    games.add( game1 );
                } while (cursor.moveToNext());
            }

            //Close Database Connection
            db.close();
        }

        //Return Game List
        return games;
    }

来自Games.java的代码

代码语言:javascript
复制
//Inserting New Game In The Database & Refreshing The List
    private void createGame(String leagueId, String bowlerId, String seriesId, String score, String spares, String strikes, String splits, String splitConversions, String openFrames) {
        //Inserting Game In The Database & Getting Newly Inserted Game Id
        long id = db.insertGame(leagueId, bowlerId, seriesId, score, strikes, spares, splits, splitConversions, openFrames);

        //Getting The Newly Inserted Game From The Database
        Game n = db.getGame(leagueId, bowlerId, seriesId);

        if (n != null) {
            //Adding New Game To The Array at Position 0
            gameList.add(0, n);

            //Refreshing The List
            mAdapter.notifyDataSetChanged();

            toggleEmptyGames();
        }
    }

    //Updating Game In The Database & Updating Item In The List By Its Position
    private void updateGame(String score, String strikes, String spares, String splits, String splitConversions, String openFrames, int position) {
        Game n = gameList.get(position);
        //Updating the Game Text
        n.setScore(score);
        n.setStrikes(strikes);
        n.setSpares(spares);
        n.setSplits(splits);
        n.setSplitConversions(splitConversions);
        n.setOpenFrames(openFrames);

        //Updating Game In The Database
        db.updateGame(n);

        //Refreshing The List
        gameList.set(position, n);
        mAdapter.notifyItemChanged(position);

        toggleEmptyGames();
    }

    //Deleting Game From SQWLite & Removing The Item From The List By Its Position
    private void deleteGame(int position) {
        //Deleting Game From The Database
        db.deleteGame(gameList.get(position));

        //Removing Game From The List
        gameList.remove(position);
        mAdapter.notifyItemRemoved(position);

        toggleEmptyGames();
    }

    //Opens Dialog With Edit - Delete Options
    private void showActionsDialog(final int position) {
        CharSequence colors[] = new CharSequence[]{"Edit", "Delete"};

        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("Choose option");
        builder.setItems(colors, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                if (which == 0) {
                    showGameDialog(true, gameList.get(position), position);
                } else {
                    deleteGame(position);
                }
            }
        });
        builder.show();
    }

此错误仅在我尝试将另一个游戏添加到数据库时出现。当我重新启动应用程序时,输入的数据出现在列表视图中,但是有些字段缺少值,这是不正确的。

修订后的代码

代码语言:javascript
复制
public Game  getGame(String leagueId, String bowlerId, String seriesId) {
        //Get Readable Database If We Are Not Inserting Anything
        SQLiteDatabase db = this.getReadableDatabase();

        Cursor cursor = db.query( Game.TABLE_NAME,
                new String[]{Game.COLUMN_ID, Game.COLUMN_LEAGUE_ID, Game.COLUMN_BOWLER_ID,
                        Game.COLUMN_SERIES_ID, Game.COLUMN_SCORE, Game.COLUMN_STRIKES, Game.COLUMN_SPARES, Game.COLUMN_SPLITS, Game.COLUMN_SPLIT_CONVERSIONS, Game.COLUMN_OPEN_FRAMES, Game.COLUMN_TIMESTAMP},
                Game.COLUMN_LEAGUE_ID + "=?" + " AND " + Game.COLUMN_BOWLER_ID + "=?" + " AND " + Game.COLUMN_SERIES_ID + "=?",
                new String[]{String.valueOf( leagueId ), String.valueOf( bowlerId ), String.valueOf( seriesId )}, null, null, null, null );


        // if (cursor.getCount()>0)
        //    cursor.moveToFirst();
        // Log.d("Events",Integer.toString(cursor.getCount()));
        if (cursor.moveToFirst()) {
            //Prepare Game Object
            Game game = new Game(

                    cursor.getInt( cursor.getColumnIndex( Game.COLUMN_ID ) ),
                    cursor.getString( cursor.getColumnIndex( Game.COLUMN_LEAGUE_ID ) ),
                    cursor.getString( cursor.getColumnIndex( Game.COLUMN_BOWLER_ID ) ),
                    cursor.getString( cursor.getColumnIndex( Game.COLUMN_SERIES_ID ) ),
                    cursor.getString( cursor.getColumnIndex( Game.COLUMN_SCORE ) ),
                    cursor.getString( cursor.getColumnIndex( Game.COLUMN_STRIKES ) ),
                    cursor.getString( cursor.getColumnIndex( Game.COLUMN_SPARES ) ),
                    cursor.getString( cursor.getColumnIndex( Game.COLUMN_SPLITS ) ),
                    cursor.getString( cursor.getColumnIndex( Game.COLUMN_SPLIT_CONVERSIONS ) ),
                    cursor.getString( cursor.getColumnIndex( Game.COLUMN_OPEN_FRAMES ) ),
                    cursor.getString( cursor.getColumnIndex( Game.COLUMN_TIMESTAMP ) ) );

            //Close Database Connection
            cursor.close();

            return game;
        } else {
        }
    }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-06-06 04:04:42

出现此错误的原因有两个。首先,查询没有返回任何行,当从方法返回的游标不是null时,您正在检查query null游标是否为null,因此查询没有正确检查/处理这些行。它可能是空的 (cursor.getCount()将返回0)。

所有的Cursor move????方法都返回true或false,这取决于是否可以进行移动。

因此,为了正确地处理读取游标,你应该永远不要使用(这是没有用的,而且在你的例子中是破坏性的) :-

代码语言:javascript
复制
if (cursor != null) {
    cursor.moveToFirst(); // (or any move???? method
    ..... Ouch if the Cursor is empty as there will be no first row to extract data from
}

相反,您应该使用:

代码语言:javascript
复制
if (cursor.moveToFirst()) {
    ..... do your stuff here
} else {
    ..... handle no row found here if wanted
}

对于游标的循环,您可以使用:-

代码语言:javascript
复制
while (cursor.moveToNext()) {
    .... handle each row here
}

如果您需要遍历游标,并且不处理游标中的任何行,则可以使用:-

代码语言:javascript
复制
if (cursor.getCount() < 1) {
    ..... handle no rows here
}
while (cursor.moveToNext()) {
    ..... handle each row here
}

请注意,在任何情况下,您都应该在使用光标时将其关闭。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50706917

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档