Как исправить SQLite: не удалось прочитать строку 0, столбец -1 из окна курсора - PullRequest
0 голосов
/ 17 мая 2019

Я сейчас создаю приложение для моего последнего проекта в школе, которое представляет собой регистратор. Пользователь сохраняет информацию, а приложение сохраняет ее в виде дневника. Я добавил значения для сохранения, такие как заголовок, дата и заметки. Все, что добавлено после этого, приводит к сбою приложения с ошибкой:

Caused by: java.lang.IllegalStateException: Couldn't read row 0, col -1 from CursorWindow.  Make sure the Cursor is initialized correctly before accessing data from it.

Я дважды проверил, где написан весь код, ошибок нет. Самым запутанным в этом отношении является то, что я могу получить два других строковых значения для хранения, но любые добавленные дополнительные вызывают сбой приложения.

Есть 5 классов, все подключены к базе данных.

FitnessLab:


    private static ContentValues getContentValues(Fitness fitness) {
        ContentValues myContentValues = new ContentValues();
        myContentValues.put(FitnessDbSchema.FitnessTable.Columns.UUID, fitness.getId().toString());
        myContentValues.put(FitnessDbSchema.FitnessTable.Columns.TITLE, fitness.getTitle());
        myContentValues.put(FitnessDbSchema.FitnessTable.Columns.NOTES, fitness.getNotes());
        myContentValues.put(FitnessDbSchema.FitnessTable.Columns.CALORIES, fitness.getCalories());
        myContentValues.put(FitnessDbSchema.FitnessTable.Columns.WORKTIME, fitness.getworkTime());
        myContentValues.put(FitnessDbSchema.FitnessTable.Columns.DATE, fitness.getDate().getTime());

        return myContentValues;
    }

    private FitnessCursorWrapper queryFitnesss(String whereClause, String[] whereArgs) {

        Cursor cursor = mDatabase.query(
                FitnessDbSchema.FitnessTable.NAME,
                null,
                whereClause,
                whereArgs,
                null,
                null,
                null);


        return new FitnessCursorWrapper(cursor);
    }

FitnessFragment

 @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_fitness, container, false);

        mTitleField = v.findViewById(R.id.fitness_title);
        mTitleField.setText(mFitness.getTitle());
        mTitleField.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence charSequence, int start, int before, int count) {
                mFitness.setTitle(charSequence.toString());

            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });

        mNotesField = v.findViewById(R.id.fitness_notes);
        mNotesField.setText(mFitness.getNotes());
        mNotesField.addTextChangedListener(new TextWatcher() {

            @Override
            public void beforeTextChanged(CharSequence charSequence, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence charSequence, int start, int before, int count) {
                mFitness.setNotes(charSequence.toString());

            }

            @Override
            public void afterTextChanged(Editable charSequence) {

            }
        });

        mCaloriesField = v.findViewById(R.id.fitness_calories);
        mCaloriesField.setText(mFitness.getCalories());
        mCaloriesField.addTextChangedListener(new TextWatcher() {

            @Override
            public void beforeTextChanged(CharSequence charSequence, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence charSequence, int start, int before, int count) {
                mFitness.setCalories(charSequence.toString());

            }

            @Override
            public void afterTextChanged(Editable charSequence) {

            }
        });

        mWorkTimeField = v.findViewById(R.id.fitness_worktime);
        mWorkTimeField.setText(mFitness.getworkTime());
        mWorkTimeField.addTextChangedListener(new TextWatcher() {

            @Override
            public void beforeTextChanged(CharSequence charSequence, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence charSequence, int start, int before, int count) {
                mFitness.setworkTime(charSequence.toString());

            }

            @Override
            public void afterTextChanged(Editable charSequence) {

            }
        });

        mDateButton = v.findViewById(R.id.fitness_date);
        updateDate();

        mDateButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                FragmentManager manager = getFragmentManager();
                DatePickerFragment dialog = DatePickerFragment.newInstance(mFitness.getDate());
                dialog.setTargetFragment(FitnessFragment.this, REQUEST_DATE);
                dialog.show(manager, DIALOG_DATE);

            }
        });

FitnessBaseHelper

public class FitnessBaseHelper extends SQLiteOpenHelper {
    private static final int VERSION = 1;
    private static final String DATABASE_NAME = "fitnessBase.db";

    public FitnessBaseHelper(Context context) {
        super(context, DATABASE_NAME, null, VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("create table " + FitnessTable.NAME + "(" +
                " _id integer primary key autoincrement, " +
                FitnessTable.Columns.UUID + ", " +
                FitnessTable.Columns.TITLE + ", " +
                FitnessTable.Columns.NOTES + "," +
                FitnessTable.Columns.CALORIES + "," +
                FitnessTable.Columns.WORKTIME + "," +
                FitnessTable.Columns.DATE +
                ")"
        );

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }
}

FitnessCursorWrapper

public class FitnessCursorWrapper extends CursorWrapper {
    public FitnessCursorWrapper (Cursor cursor) {
        super(cursor);
    }

    public Fitness getFitness() {
        String uuidString = getString(getColumnIndex(FitnessDbSchema.FitnessTable.Columns.UUID));
        String title = getString(getColumnIndex(FitnessDbSchema.FitnessTable.Columns.TITLE));
        String notes = getString(getColumnIndex(FitnessDbSchema.FitnessTable.Columns.NOTES));
        String calories = getString(getColumnIndex(FitnessDbSchema.FitnessTable.Columns.CALORIES));
        String worktime = getString(getColumnIndex(FitnessDbSchema.FitnessTable.Columns.WORKTIME));
        long date = getLong(getColumnIndex(FitnessDbSchema.FitnessTable.Columns.DATE));

        Fitness fitness = new Fitness(UUID.fromString(uuidString));
        fitness.setTitle(title);
        fitness.setNotes(notes);
        fitness.setCalories(calories);
        fitness.setworkTime(worktime);
        fitness.setDate(new Date(date));

        return fitness;
    }

}

FitnessDbSchema

public class FitnessDbSchema {
    public static final class FitnessTable{
        public static final String NAME = "fitnesss";

        public static final class Columns{
            public static final String UUID = "uuid";
            public static final String TITLE = "title";
            public static final String NOTES = "notes";
            public static final String CALORIES = "calories";
            public static final String WORKTIME = "worktime";
            public static final String DATE = "date";
        }
    }

}

Журнал ошибок

2019-05-16 10:23:24.523 5543-5543/com.ctech.chloe.fitnesslog E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.ctech.chloe.fitnesslog, PID: 5543
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.ctech.chloe.fitnesslog/com.ctech.chloe.fitnesslog.FitnessListActivity}: java.lang.IllegalStateException: Couldn't read row 0, col -1 from CursorWindow.  Make sure the Cursor is initialized correctly before accessing data from it.
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2665)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
        at android.app.ActivityThread.-wrap12(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        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)
     Caused by: java.lang.IllegalStateException: Couldn't read row 0, col -1 from CursorWindow.  Make sure the Cursor is initialized correctly before accessing data from it.
        at android.database.CursorWindow.nativeGetString(Native Method)
        at android.database.CursorWindow.getString(CursorWindow.java:438)
        at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:51)
        at android.database.CursorWrapper.getString(CursorWrapper.java:137)
        at com.ctech.chloe.fitnesslog.database.FitnessCursorWrapper.getFitness(FitnessCursorWrapper.java:19)
        at com.ctech.chloe.fitnesslog.FitnessLab.getFitnesss(FitnessLab.java:68)
        at com.ctech.chloe.fitnesslog.FitnessListFragment.updateUI(FitnessListFragment.java:85)
        at com.ctech.chloe.fitnesslog.FitnessListFragment.onCreateView(FitnessListFragment.java:43)
        at android.support.v4.app.Fragment.performCreateView(Fragment.java:2439)
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1460)
        at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1784)
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1852)
        at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:802)
        at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2625)
        at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2411)
        at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2366)
        at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2273)
        at android.support.v4.app.FragmentManagerImpl.dispatchStateChange(FragmentManager.java:3273)
        at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:3229)
        at android.support.v4.app.FragmentController.dispatchActivityCreated(FragmentController.java:201)
        at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:620)
        at android.support.v7.app.AppCompatActivity.onStart(AppCompatActivity.java:178)
        at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1248)
        at android.app.Activity.performStart(Activity.java:6696)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2628)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726) 
        at android.app.ActivityThread.-wrap12(ActivityThread.java) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477) 
        at android.os.Handler.dispatchMessage(Handler.java:102) 
        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) 

Я прошу прощения, если здесь слишком много кода, но я, честно говоря, не знаю, что делать, чтобы это исправить. Мой учитель ушел, и мне нужно завершить проект, но эта ошибка немного отбрасывает меня назад.

1 Ответ

2 голосов
/ 17 мая 2019

Я добавил значения для сохранения, такие как заголовок, дата и заметки.Все, что было добавлено после этого, приводит к сбою приложения с ошибкой

. Это заставляет меня думать, что вы используете старую версию базы данных.Вы можете проверить это, проверив базу данных.Есть несколько способов сделать это, описанные здесь: Просмотр содержимого файла базы данных в Android Studio .Или вы можете проверить это, очистив данные приложения или удалив его (это приведет к удалению базы данных с устройства).

Как правило, вы должны реализовать метод onUpgrade() в вашем SQLiteOpenHelper для обработки изменений схемы базы данных.

Кстати, хорошей практикой является явное объявление типов столбцов.Вы делаете это сейчас только для _id столбца.Должно быть что-то вроде этого (основано на Fitness типах полей):

db.execSQL("create table " + FitnessTable.NAME + "(" +
            " _id integer primary key autoincrement, " +
            FitnessTable.Columns.UUID + " TEXT , " +
            FitnessTable.Columns.TITLE + " TEXT, " +
            FitnessTable.Columns.NOTES + " TEXT, " +
            FitnessTable.Columns.CALORIES + " TEXT, " + 
            FitnessTable.Columns.WORKTIME + " TEXT, " +
            FitnessTable.Columns.DATE + " INTEGER " +
            ")"
...