【问题标题】:I'm getting the following error from the CursorAdapter Make sure the Cursor is initialized correctly before accessing data from it我从 CursorAdapter 收到以下错误 请确保在从光标访问数据之前正确初始化光标
【发布时间】:2018-10-24 14:50:29
【问题描述】:

我的活页夹类

public void bindView(View view, Context context, Cursor cursor) {


            mTitleText = (TextView) view.findViewById(R.id.recycle_title);
            mDateAndTimeText = (TextView) view.findViewById(R.id.recycle_date_time);
            mRepeatInfoText = (TextView)view.findViewById(R.id.recycle_repeat_info);
            mActiveImage = (ImageView) view.findViewById(R.id.active_image);
            mThumbnailImage = (ImageView) view.findViewById(R.id.thumbnail_image);

           int titleColumnIndex = cursor.getColumnIndex(AlarmReminderContract.AlarmReminderEntry.KEY_TITLE);
            int dateColumnIndex = cursor.getColumnIndex(AlarmReminderContract.AlarmReminderEntry.KEY_DATE);
            int timeColumnIndex = cursor.getColumnIndex(AlarmReminderContract.AlarmReminderEntry.KEY_TIME);
            int repeatColumnIndex = cursor.getColumnIndex(AlarmReminderContract.AlarmReminderEntry.KEY_REPEAT);
            int repeatNoColumnIndex = cursor.getColumnIndex(AlarmReminderContract.AlarmReminderEntry.KEY_REPEAT_NO);
            int repeatTypeColumnIndex = cursor.getColumnIndex(AlarmReminderContract.AlarmReminderEntry.KEY_REPEAT_TYPE);
            int activeColumnIndex = cursor.getColumnIndex(AlarmReminderContract.AlarmReminderEntry.KEY_ACTIVE);
            int locationColumnIndex= cursor.getColumnIndex(AlarmReminderContract.AlarmReminderEntry.KEY_LOCATION);

            String title = cursor.getString(titleColumnIndex);
            String date = cursor.getString(dateColumnIndex);
            String time = cursor.getString(timeColumnIndex);
            String repeat = cursor.getString(repeatColumnIndex);
            String repeatNo = cursor.getString(repeatNoColumnIndex);
            String repeatType = cursor.getString(repeatTypeColumnIndex);
            String active = cursor.getString(locationColumnIndex);
            String loc = cursor.getString(activeLocation);
            String dateTime = date + " " + time;
            Log.e("msg_fa", loc);
            if (loc.equals(false)) {
                setReminderTitle(title);
                setReminderDateTime(dateTime);
                setReminderRepeatInfo(repeat, repeatNo, repeatType);
                setActiveImage(active);

            } else
            {
                setReminderTitle(title);
                setReminderDateTime("Place");
            }

    }

我的 Logcat 错误

         E/CursorWindow: Failed to read row 0, column 8 from a CursorWindow which has 1 rows, 8 columns.
            2018-10-24 19:54:06.958 11109-11109/? E/AndroidRuntime: FATAL EXCEPTION: main
                Process:PID: 11109
                java.lang.IllegalStateException: Couldn't read row 0, col 8 from CursorWindow.  Make sure the Cursor is initialized correctly before accessing data from it.

我可以访问直到数据 columnIndex 7,但我无法从 8 获取索引

我的数据库助手的代码

         public void onCreate(SQLiteDatabase sqLiteDatabase) {
            // Create a String that contains the SQL statement to create the reminder table
            String SQL_CREATE_ALARM_TABLE =  "CREATE TABLE " + AlarmReminderContract.AlarmReminderEntry.TABLE_NAME + " ("
                    + AlarmReminderContract.AlarmReminderEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
                    + AlarmReminderContract.AlarmReminderEntry.KEY_TITLE + " TEXT NOT NULL, "
                    + AlarmReminderContract.AlarmReminderEntry.KEY_DATE + " TEXT, "
                    + AlarmReminderContract.AlarmReminderEntry.KEY_TIME + " TEXT, "
                    + AlarmReminderContract.AlarmReminderEntry.KEY_REPEAT + " TEXT, "
                    + AlarmReminderContract.AlarmReminderEntry.KEY_REPEAT_NO + " TEXT, "
                    + AlarmReminderContract.AlarmReminderEntry.KEY_REPEAT_TYPE + " TEXT, "
                    + AlarmReminderContract.AlarmReminderEntry.KEY_ACTIVE + " TEXT,"
                    +AlarmReminderContract.AlarmReminderEntry.KEY_LOCATION + " TEXT,"
                    + AlarmReminderContract.AlarmReminderEntry.latitude+" TEXT ,"
                    + AlarmReminderContract.AlarmReminderEntry.longitude+" TEXT" +" );";

            // Execute the SQL statement
            sqLiteDatabase.execSQL(SQL_CREATE_ALARM_TABLE);

插入数据库工作完美,但是当我要求从第 8 个索引中获取数据时出现此问题

我面临的主要问题是,当我尝试从 KEY_LOCATION 的索引中获取值时,应用程序崩溃了,然后它给出了显示在 logcat 中的错误,直到第 7 列我才得到值尝试更新数据库版本并更改表名和数据库名它没有按预期工作。

这是我的提供者类

public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
                        String sortOrder) {
        SQLiteDatabase database = mDbHelper.getReadableDatabase();

        // This cursor will hold the result of the query
        Cursor cursor = null;

        int match = sUriMatcher.match(uri);
        switch (match) {
            case REMINDER:
                cursor = database.query(AlarmReminderContract.AlarmReminderEntry.TABLE_NAME, projection, selection, selectionArgs,
                        null, null, sortOrder);
                Log.i("msg","Reminder Invoked");
                break;
            case REMINDER_ID:
                selection = AlarmReminderContract.AlarmReminderEntry._ID + "=?";
                selectionArgs = new String[] { String.valueOf(ContentUris.parseId(uri)) };


                cursor = database.query(AlarmReminderContract.AlarmReminderEntry.TABLE_NAME, projection, selection, selectionArgs,
                        null, null, sortOrder);
                break;
            default:
                throw new IllegalArgumentException("Cannot query unknown URI " + uri);
        }

【问题讨论】:

  • 把你的游标查询放在首位。还有游标的循环代码
  • 问题可能是您没有更改表结构(尽管您说您已经更新了数据库版本)或者获取光标的查询没有选择 KEY_LOCATIONS 列(SELECT * FROM ..... 将选择所有列)。我建议删除应用程序的数据(这将排除 onUpgrade 方法不合适)然后重新运行。如果问题仍然存在,请编辑您的问题以包含返回光标的查询。
  • 我没有使用任何循环我直接获取列索引插入工作正常,而在获取数据时我只是获取索引值。我尝试删除应用程序并更新数据库。正如我之前提到的,我可以从索引 8 中获取数据。索引 0-7 完美运行
  • 那么您为什么不编辑您的问题以包含查询,这将是最有可能的问题?
  • 根据您的要求,我已经更新了问题

标签: java android sqlite android-studio android-sqlite


【解决方案1】:

问题是光标在表中的 11 个(偏移量 0-10)列中只有 8 个(偏移量 0-7)。因此,消息说它未能读取第 0 行(第一行)第 8 列(第 9 列(位置))。

游标将仅包含您隐式或显式指定的列(SELECT * 表示所有列,null 作为 SQLIteDatabase 查询方法的第二个参数等同于 SELECT *,因此表示所有列)。这与基础表中的列无关。

您的问题似乎是作为第二个参数(投影)传递给提供者类的字符串数组仅明确指定了 8 列。

快速修复(尽管是最灵活的修复)是在调用 SQLiteDatabase query 时使用 projectionnull insetad 作为第二个参数> 方法。

所以不是:-

database.query(AlarmReminderContract.AlarmReminderEntry.TABLE_NAME, projection, selection, selectionArgs,
                    null, null, sortOrder);

你可以使用:-

database.query(AlarmReminderContract.AlarmReminderEntry.TABLE_NAME, null, selection, selectionArgs,
                    null, null, sortOrder);

因此,整个查询方法可以是:-

public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
                    String sortOrder) {
    SQLiteDatabase database = mDbHelper.getReadableDatabase();

    // This cursor will hold the result of the query
    Cursor cursor = null;

    int match = sUriMatcher.match(uri);
    switch (match) {
        case REMINDER:
            cursor = database.query(AlarmReminderContract.AlarmReminderEntry.TABLE_NAME, 
                    null, //<<<<<<<<<< CHANGED 
                    selection, 
                    selectionArgs,
                    null, null, sortOrder);
            Log.i("msg","Reminder Invoked");
            break;
        case REMINDER_ID:
            selection = AlarmReminderContract.AlarmReminderEntry._ID + "=?";
            selectionArgs = new String[] { String.valueOf(ContentUris.parseId(uri)) };


            cursor = database.query(AlarmReminderContract.AlarmReminderEntry.TABLE_NAME, 
                    null, //<<<<<<<<<< CHANGED 
                    selection, 
                    selectionArgs,
                    null, null, sortOrder);
            break;
        default:
            throw new IllegalArgumentException("Cannot query unknown URI " + uri);
    }
}
  • 请注意,传递给方法的第二个参数String[] projection 是多余的。

另一种方法是修改对 Provider 类的 query 方法的调用(如上),以便在调用 Provider 类的 query 时传递的字符串数组包含额外的列 方法。

例如

String[] projection_columns = new String[]{
    AlarmReminderContract.AlarmReminderEntry._ID,
    AlarmReminderContract.AlarmReminderEntry.KEY_TITLE,
    AlarmReminderContract.AlarmReminderEntry.KEY_DATE,
    AlarmReminderContract.AlarmReminderEntry.KEY_TIME,
    AlarmReminderContract.AlarmReminderEntry.KEY_REPEAT,
    AlarmReminderContract.AlarmReminderEntry.KEY_REPEAT_NO,
    AlarmReminderContract.AlarmReminderEntry.KEY_REPEAT_TYPE,
    AlarmReminderContract.AlarmReminderEntry.KEY_LOCATION,
    AlarmReminderContract.AlarmReminderEntry.KEY_ACTIVE,
    AlarmReminderContract.AlarmReminderEntry.latitude,
    AlarmReminderContract.AlarmReminderEntry.longitude
}

your_provider.query(your_uri, project_columns,your_selection, your_selectionargs, you_sortorder);

【讨论】:

  • 感谢您的帮助 已修复。正如你上面提到的,我忘了在投影中声明它们
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-05-16
  • 2017-01-01
  • 1970-01-01
  • 2018-02-27
  • 1970-01-01
  • 1970-01-01
  • 2016-07-28
相关资源
最近更新 更多