java - java.lang.IllegalStateException: Couldn'

2019-02-13 18:33发布

问题:

I'm creating an app which uses SQLiteDatabase to store items of a ListView. But, I get an error while populating the data in the ListView from the Database, and the app crashes.

Here's my Database -

import java.util.ArrayList;

import android.content.ContentValues;
import android.content.Context;

import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class NotesDatabase extends SQLiteOpenHelper {

private static final String NOTE_NAME = "name";
private static final String NOTE_ID = "id";
private static final String NOTE_SUBJECT = "subject";

private static final String DATABASE_NAME = "notesDatabase";
private static final String TABLE_NOTES = "notes";
private static final int DATABASE_VERSION = 1;
private static final String CREATE_NOTES_TABLE = "CREATE TABLE " + TABLE_NOTES + "("
        + NOTE_ID + " INTEGER PRIMARY KEY," + NOTE_NAME + " TEXT,"
        + NOTE_SUBJECT + " TEXT" + ")";
public NotesDatabase(Context context) {
    super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {

    try {
        db.execSQL(CREATE_NOTES_TABLE);
    }
    catch(SQLException e) {
        e.printStackTrace();
    }
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    db.execSQL("DROP TABLE IF EXSISTS topics");
    onCreate(db);
}
public void addNote(Note note) {
    SQLiteDatabase db = this.getWritableDatabase();

    ContentValues notes = new ContentValues();
    notes.put(NOTE_NAME, note.getNote());
    notes.put(NOTE_SUBJECT, note.getSubject());

    db.insert(TABLE_NOTES, null, notes);
    db.close();
}
public void removeNote(Note note) {

    SQLiteDatabase db = this.getWritableDatabase();

    db.delete(TABLE_NOTES, NOTE_NAME + " = ?", 
            new String[] {note.getNote()});

    db.close();
}
public ArrayList<Note> getNotes(){

    ArrayList<Note> notes = new ArrayList<Note>();

    String selectQuery = "SELECT * FROM " + TABLE_NOTES;

    SQLiteDatabase db = this.getWritableDatabase();
    Cursor cur = db.rawQuery(selectQuery, null);

    if(cur.moveToFirst()) {
        do {
            Note note = new Note();
            note.setId(Integer.parseInt(cur.getString(0)));
            note.setNote(cur.getString(cur.getColumnIndex(NOTE_NAME)));
            note.setSubject(cur.getString(cur.getColumnIndex(NOTE_SUBJECT)));
            notes.add(note);
        } while(cur.moveToNext());
    }
    db.close();
    return notes;
}
public void updateNote(String old_name, String new_name) {
    SQLiteDatabase db = this.getWritableDatabase();

    ContentValues topic = new ContentValues();

    topic.put(NOTE_NAME, new_name);

    db.update(TABLE_NOTES, topic, NOTE_NAME + " = ?", 
            new String[] {old_name});
    db.close();
}
}

Note.java -

public class Note {

String _Note;
int _id;
String subject;

public String getSubject() {
    return subject;
}
public void setSubject(String subject) {
    this.subject = subject;
}
public Note() {

}
public Note(int id, String Note, String Subject) {
    this._id = id;
    this._Note = Note;
    this.subject = Subject;
}
public Note(String Note, String Subject) {
    this._Note = Note;
    this.subject = Subject;
}
public Note(String Note) {
    this._Note = Note;
}
public String getNote() {
    return _Note;
}
public void setNote(String _Note) {
    this._Note = _Note;
}
public int getId() {
    return _id;
}
public void setId(int _id) {
    this._id = _id;
}

}

NotesDatabase.java -

import java.util.ArrayList;

import android.os.Bundle;

import android.app.Activity;

import android.content.Intent;

import android.util.Log;

import android.view.Menu;
import android.view.View;

import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class Notes_page extends Activity {

ArrayList<Note> notes = new ArrayList<Note>();

NotesDatabase ndb = new NotesDatabase(this);
private NoteAdapter adapter;

private ListView notes_list;
private TextView subject_display;

String subject;

int requestCode = 1;

@Override
public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_notes_page);

    notes_list = (ListView) findViewById(R.id.notes);
    ndb.getWritableDatabase();
    notes = ndb.getNotes();
    adapter = new NoteAdapter(this, notes);

    subject = getIntent().getStringExtra("SUBJECT_NAME");

    notes_list.setAdapter(adapter);

    subject_display = (TextView) findViewById(R.id.subject_name);
    subject_display.setText(subject);
}

public void onClickAddNewNote(View v) {
    startActivityForResult(new Intent("com.Swap.Add_New_Note"), requestCode);

}

public void onActivityResult(int request_Code, int result_Code, Intent i) {
    if(request_Code == requestCode) {
        if(result_Code == RESULT_OK) {
            Note mNote = new Note(i.getStringExtra("NOTE"), getIntent().getStringExtra("SUBJECT_NAME"));
            ndb.getWritableDatabase();
            ndb.addNote(mNote);
            Log.d("AddNote", "Note Succesfully Added to Database");
            adapter.add(mNote);
            adapter.notifyDataSetChanged();

            Toast.makeText(getBaseContext(), mNote.getNote(), Toast.LENGTH_SHORT).show();
        }
    }
} 

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.activity_notes_page, menu);
    return true;
}
}

Here's the LogCat Error log -

04-13 22:17:10.766: E/linker(25692): load_library(linker.cpp:759): library "libmaliinstr.so" not found
04-13 22:17:14.816: E/CursorWindow(25692): Failed to read row 0, column -1 from a CursorWindow which has 1 rows, 2 columns.
04-13 22:17:14.869: E/AndroidRuntime(25692): FATAL EXCEPTION: main
04-13 22:17:14.869: E/AndroidRuntime(25692): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.Swap.RR/com.Swap.RR.Notes_page}: java.lang.IllegalStateException: Couldn't read row 0, col -1 from CursorWindow.  Make sure the Cursor is initialized correctly before accessing data from it.
04-13 22:17:14.869: E/AndroidRuntime(25692):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2364)
04-13 22:17:14.869: E/AndroidRuntime(25692):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2416)
04-13 22:17:14.869: E/AndroidRuntime(25692):    at android.app.ActivityThread.access$600(ActivityThread.java:174)
04-13 22:17:14.869: E/AndroidRuntime(25692):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1382)
04-13 22:17:14.869: E/AndroidRuntime(25692):    at android.os.Handler.dispatchMessage(Handler.java:107)
04-13 22:17:14.869: E/AndroidRuntime(25692):    at android.os.Looper.loop(Looper.java:194)
04-13 22:17:14.869: E/AndroidRuntime(25692):    at android.app.ActivityThread.main(ActivityThread.java:5409)
04-13 22:17:14.869: E/AndroidRuntime(25692):    at java.lang.reflect.Method.invokeNative(Native Method)
04-13 22:17:14.869: E/AndroidRuntime(25692):    at java.lang.reflect.Method.invoke(Method.java:525)
04-13 22:17:14.869: E/AndroidRuntime(25692):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
04-13 22:17:14.869: E/AndroidRuntime(25692):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:606)
04-13 22:17:14.869: E/AndroidRuntime(25692):    at dalvik.system.NativeStart.main(Native Method)
04-13 22:17:14.869: E/AndroidRuntime(25692): 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.
04-13 22:17:14.869: E/AndroidRuntime(25692):    at android.database.CursorWindow.nativeGetString(Native Method)
04-13 22:17:14.869: E/AndroidRuntime(25692):    at android.database.CursorWindow.getString(CursorWindow.java:434)
04-13 22:17:14.869: E/AndroidRuntime(25692):    at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:51)
04-13 22:17:14.869: E/AndroidRuntime(25692):    at com.Swap.RR.NotesDatabase.getNotes(NotesDatabase.java:78)
04-13 22:17:14.869: E/AndroidRuntime(25692):    at com.Swap.RR.Notes_page.onCreate(Notes_page.java:41)
04-13 22:17:14.869: E/AndroidRuntime(25692):    at android.app.Activity.performCreate(Activity.java:5122)
04-13 22:17:14.869: E/AndroidRuntime(25692):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1146)
04-13 22:17:14.869: E/AndroidRuntime(25692):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2328)
04-13 22:17:14.869: E/AndroidRuntime(25692):    ... 11 more

Please help me figure out what's wrong with me code. Thanks in advance!!

回答1:

Your subject line is misleading. The exception in your stacktrace says

Couldn't read row 0, col -1 from CursorWindow

which essentially means that getColumnIndex() could not find the specified column in the Cursor and -1 was returned as column index.

Your selection SELECT * contains all columns from the table.

Your CREATE TABLE seems to contain all columns you're requesting the index of with getColumnIndex() in getNotes().

Chances are that you've added a column but the test device still has a database file without that column. Just uninstall your app or clear its data to remove the old database file and make your onCreate() recreate the database on the next run.



回答2:

There can be a difference between the column name in the table and the name you are giving to access that column in your code. So you should recheck the name, because in my case there was a spelling mistake :P