我一直在学习如何在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)
答案 0 :(得分:2)
无法从具有6行3的CursorWindow读取第0行第3列 列。
是一个线索,它说无法从光标的第4列(偏移3)获取值,因为只有3列(0,1和2)。
原因很可能是您更改了数据库结构(添加了列),只是重新运行应用程序,假设onCreate
方法将运行并应用更改。
onCreate
方法实际上只在首次创建数据库时自动运行。
解决这个问题的方法是执行以下操作之一: -
onUpgrade
方法,在DROPping(删除)后,TABLE将调用'onCreate'方法。注意!所有3都将导致现有数据丢失。如果您需要保留数据,则必须使用其他方法。