加载SQlite数据库时出错

时间:2017-10-22 16:37:27

标签: android sqlite android-sqlite

我一直在学习如何在Android中创建和加载SQLite数据库,我尝试修改我发现的教程。 Link到原始教程

我已经能够启动并运行,但我尝试修改它以接受四个输入,两个文本字符串和两个数字(现在将它们保存为字符串)。每当我尝试运行OpenViewData时,它都会崩溃,我无法理解为什么。

我的主要活动是:

public class MainActivity extends AppCompatActivity {

public Button Save;
public  Button View;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Save = (Button)findViewById(R.id.Save);
    View = (Button)findViewById(R.id.View);


    Save.setOnClickListener(new android.view.View.OnClickListener() {
        @Override
        public void onClick(android.view.View view) {
            SaveButtonHit();
        }
    });

    View.setOnClickListener(new android.view.View.OnClickListener() {
        @Override
        public void onClick(View view) {

            OpenViewData();
        }
    });


}
void SaveButtonHit(){


    EditText Word1 = (EditText)findViewById(R.id.Word1);
    EditText Word2 = (EditText)findViewById(R.id.Word2);
    EditText Num1 = (EditText)findViewById(R.id.Number1);
    EditText Num2 = (EditText)findViewById(R.id.Number2);

    String ReceivedWord1 = Word1.getText().toString();
    String ReceivedWord2 = Word2.getText().toString();
    String ReceivedNum1 =  Num1.getText().toString();
    String ReceivedNum2 =  Num2.getText().toString();


    Toast.makeText(getApplicationContext(), "words read", Toast.LENGTH_SHORT).show();
    DatabaseHandler db = new DatabaseHandler(this);

    db.addContact(new Contact(ReceivedWord1, ReceivedWord2, ReceivedNum1, ReceivedNum2));
    db.close();
}



void OpenViewData(){

    DatabaseHandler db = new DatabaseHandler(this);
    List contacts = db.getAllContacts();
    Iterator var5 = contacts.iterator();

      while(var5.hasNext()) {
        Contact cn = (Contact)var5.next();
        String log = "Id: " + cn.getID() + " ,WORD1: " + cn.getWord1() + " ,WORD2: " + cn.getWord2()+ " ,NUM1: " + cn.getNum1()+ " ,NUM2: " + cn.getNum2();
        Log.d("Name: ", log);
    }

  }
}

我的联系人课程是:

public class Contact {
private int _id;
private String _word1;
private String _word2;
private String _num1;
private String _num2;

public Contact() {
}

public Contact(int id, String _word1, String _word2, String _num1, String _num2) {
    this._id = id;
    this._word1 = _word1;
    this._word2 = _word2;
    this._num1 = _num1;
    this._num2 = _num2;
}

public Contact(String _word1, String _word2, String _num1, String _num2) {
    this._word1 = _word1;
    this._word2 = _word2;
    this._num1 = _num1;
    this._num2 = _num2;
}

public int getID() {
    return this._id;
}

public void setID(int id) {
    this._id = id;
}

public String getWord1() {
    return this._word1;
}

public void setWord1(String word1) {
    this._word1 = word1;
}

public String getWord2() {
    return this._word2;
}


public void setWord2(String word2) {
    this._word2 = word2;
}


public String getNum1() {
    return this._num1;
}

public void setNum1(String num1) {
    this._num1 = num1;
}


public String getNum2() {
    return this._num2;
}

public void setNum2(String num2) {
    this._num2 = num2;
  }

}

我的帮助班是:

public class DatabaseHandler extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "test_database";
private static final String TABLE_CONTACTS = "contacts";
private static final String KEY_ID = "id";
private static final String KEY_WORD1 = "word1";
private static final String KEY_WORD2 = "word2";
private static final String KEY_NUM1 = "num1";
private static final String KEY_NUM2 = "num2";

public DatabaseHandler(Context context) { super(context, "test_database", null, 1); }

public void onCreate(SQLiteDatabase db) {

    String CREATE_CONTACTS_TABLE = "CREATE TABLE contacts(id INTEGER PRIMARY KEY,word1 TEXT,word2 TEXT,num1 TEXT,num2 TEXT)";
    db.execSQL(CREATE_CONTACTS_TABLE);
    Log.d("Reading: ", "Reading all contacts..");

}

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

        db.execSQL("DROP TABLE IF EXISTS contacts");
        this.onCreate(db);
}

void addContact(Contact contact) {

    SQLiteDatabase db = this.getWritableDatabase();
    ContentValues values = new ContentValues();
    values.put("word1", contact.getWord1());
    values.put("word2", contact.getWord2());
    values.put("num1",  contact.getNum1());
    values.put("num1",  contact.getNum2());
    db.insert("contacts", null, values);
    db.close();

}

Contact getContact(int id) {
    SQLiteDatabase db = this.getReadableDatabase();
    Cursor cursor = db.query("contacts", new String[]{"id", "word1", "word2", "num1", "num2"}, "id=?", new String[]{String.valueOf(id)}, null, null, null, null);

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

    Contact contact = new Contact(Integer.parseInt(cursor.getString(0)), cursor.getString(1), cursor.getString(2), cursor.getString(3), cursor.getString(4));
    cursor.close();
    return contact;
}

public List<Contact> getAllContacts() {

    ArrayList contactList = new ArrayList();
    String selectQuery = "SELECT  * FROM contacts";
    SQLiteDatabase db = this.getWritableDatabase();
    Cursor cursor = db.rawQuery(selectQuery, null);

    if(cursor.moveToFirst()) {

        do {

            Contact contact = new Contact();
            contact.setID(Integer.parseInt(cursor.getString(0)));
            contact.setWord1(cursor.getString(1));
            contact.setWord2(cursor.getString(2));
            contact.setNum1(cursor.getString(3));
            contact.setNum2(cursor.getString(4));
            contactList.add(contact);

        } while(cursor.moveToNext());
    }

    cursor.close();
    return contactList;
}

public int updateContact(Contact contact) {

    SQLiteDatabase db = this.getWritableDatabase();
    ContentValues values = new ContentValues();
    values.put("word1", contact.getWord1());
    values.put("word2", contact.getWord2());
    return db.update("contacts", values, "id = ?", new String[]{String.valueOf(contact.getID())});

}

public void deleteContact(Contact contact) {

    SQLiteDatabase db = this.getWritableDatabase();
    db.delete("contacts", "id = ?", new String[]{String.valueOf(contact.getID())});
    db.close();

}

public int getContactsCount() {

    String countQuery = "SELECT  * FROM contacts";
    SQLiteDatabase db = this.getReadableDatabase();
    Cursor cursor = db.rawQuery(countQuery, (String[])null);
    cursor.close();
    return cursor.getCount();

  }
  }

编辑1:

Android Monitor出错:

10-22 12:46:06.554 4936-4943/? E/art: Failed sending reply to debugger: Broken pipe

EDIT2: 我认为是完整的错误日志??

10-22 12:46:02.858 4683-4683/? E/CursorWindow: Failed to read row 0, column 3 from a CursorWindow which has 6 rows, 3 columns.
10-22 12:46:02.858 4683-4683/? D/AndroidRuntime: Shutting down VM
10-22 12:46:02.858 4683-4683/? E/AndroidRuntime: FATAL EXCEPTION: main
                                                 Process: com.sahxyapps.yetanotherdatabasetutorial, PID: 4683
                                                 java.lang.IllegalStateException: Couldn't read row 0, col 3 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 com.sahxyapps.yetanotherdatabasetutorial.DatabaseHandler.getAllContacts(DatabaseHandler.java:73)
                                                     at com.sahxyapps.yetanotherdatabasetutorial.MainActivity.OpenViewData(MainActivity.java:71)
                                                     at com.sahxyapps.yetanotherdatabasetutorial.MainActivity$2.onClick(MainActivity.java:39)
                                                     at android.view.View.performClick(View.java:5610)
                                                     at android.view.View$PerformClick.run(View.java:22265)
                                                     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:6077)
                                                     at java.lang.reflect.Method.invoke(Native Method)
                                                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
                                                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)

1 个答案:

答案 0 :(得分:2)

  

无法从具有6行3的CursorWindow读取第0行第3列   列。

是一个线索,它说无法从光标的第4列(偏移3)获取值,因为只有3列(0,1和2)。

原因很可能是您更改了数据库结构(添加了列),只是重新运行应用程序,假设onCreate方法将运行并应用更改。

onCreate方法实际上只在首次创建数据库时自动运行。

解决这个问题的方法是执行以下操作之一: -

  • 删除应用程序的数据并重新运行(这将删除数据库)。
  • 卸载应用程序并重新运行(删除数据,从而删除数据库)。
  • 将DATABASE_VERSION从1更改为2并重新运行。这将导致调用onUpgrade方法,在DROPping(删除)后,TABLE将调用'onCreate'方法。

注意!所有3都将导致现有数据丢失。如果您需要保留数据,则必须使用其他方法。