我从CursorAdapter中收到以下错误:在从游标访问数据之前,请确保游标已正确初始化

时间:2018-10-24 14:50:29

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

我的活页夹类

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);
        }

1 个答案:

答案 0 :(得分:1)

问题在于,光标在表中的11列(偏移量0-10)中只有8列(偏移量0-7)。因此,该消息表明它无法读取第0行(第一行)第8列(第9列(位置))。

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

您的问题似乎是作为第二个参数(投影)传递给提供程序类的String数组仅显式指定8列。

一种快速解决方法(尽管最灵活的解决方法)是在调用SQLiteDatabase query 时将 projection null 插入作为第二个参数>方法。

所以不是:-

onCreateView

您可以使用:-

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); } } 将是多余的。

另一种方法是修改对Provider类的 query 方法的调用(如上所述),以使传递的String数组在调用Provider类的 query时包括额外的列方法。

例如

String[] projection