SQLiteOpenHelper使Android应用程序崩溃
我学习了如何使用android SDK处理SQLite数据库的教程。我的问题是,当我调用方法“getUsername()”时,应用程序崩溃。我做错了什么SQLiteOpenHelper使Android应用程序崩溃,android,sqliteopenhelper,Android,Sqliteopenhelper,我学习了如何使用android SDK处理SQLite数据库的教程。我的问题是,当我调用方法“getUsername()”时,应用程序崩溃。我做错了什么 package racenet.racenet; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase
package racenet.racenet;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class Preferences extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 2;
private static final String DATABASE_NAME = "racenet.racenet.db";
Preferences(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE settings(key TEXT, value TEXT)");
values = new ContentValues();
values.put("user_name", "");
getWritableDatabase().insert("settings", null, values);
}
@Override
public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {
}
public String getUsername() {
Cursor c = getReadableDatabase().query("settings", new String[]{"value"},
"key = 'user_name'", null, null, null, null);
c.moveToFirst();
String username = c.getString(0);
c.close();
return username;
}
}
有一件事肯定会使应用程序崩溃,那就是不要关闭方法中使用的数据库对象。您需要这样重写它:
public String getUsername() {
SQLiteDatabase database = getReadableDatabase();
Cursor c = getReadableDatabase().query("settings", new String[]{"value"},
"key = 'user_name'", null, null, null, null);
c.moveToFirst();
String username = c.getString(0);
c.close();
database.close();
return username;
}
编辑使用@slukian观察法扩展我的答案以使其更完整:您不应该从onCreate
或onUpgrade
方法中调用getWritableDatabase()
或getReadableDatabase()
。实际上你甚至不需要。将此方法重写为:
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE settings(key TEXT, value TEXT)");
values = new ContentValues();
values.put("user_name", "");
db.insert("settings", null, values);
}
请注意,我只是使用传入的
db
对象,就像您在上面几行中所做的那样。有一件事肯定会使您的应用程序崩溃,那就是您不会关闭您在方法中使用的数据库对象。您需要这样重写它:
public String getUsername() {
SQLiteDatabase database = getReadableDatabase();
Cursor c = getReadableDatabase().query("settings", new String[]{"value"},
"key = 'user_name'", null, null, null, null);
c.moveToFirst();
String username = c.getString(0);
c.close();
database.close();
return username;
}
编辑使用@slukian观察法扩展我的答案以使其更完整:您不应该从onCreate
或onUpgrade
方法中调用getWritableDatabase()
或getReadableDatabase()
。实际上你甚至不需要。将此方法重写为:
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE settings(key TEXT, value TEXT)");
values = new ContentValues();
values.put("user_name", "");
db.insert("settings", null, values);
}
请注意,我只是使用传入的db
对象,就像上面几行一样。您好,请尝试以下操作:
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE settings (key TEXT, value TEXT);");
values = new ContentValues();
// First argument of the put method is a column name
// Second argument is an inserted value
values.put("key", "user_name");
values.put("value", "user_value");
db.insert("settings", null, values);
}
// This method will drop your table and create a new one if you have changed
// the database version
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS settings");
onCreate(db);
}
嗨,试试这个:
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE settings (key TEXT, value TEXT);");
values = new ContentValues();
// First argument of the put method is a column name
// Second argument is an inserted value
values.put("key", "user_name");
values.put("value", "user_value");
db.insert("settings", null, values);
}
// This method will drop your table and create a new one if you have changed
// the database version
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS settings");
onCreate(db);
}
因为您编写了
c.moveToFirst();
不检查c
是否有行
无论如何。。
c没有行,因为您没有正确添加行
只需正确地添加值“Taras Feschuk”的答案中提到的值。
无论何时编写
c.moveToFirst()
。首先检查if(c.getCount()>0)
由于编写
c.moveToFirst();
不检查c
是否有行
无论如何。。
c没有行,因为您没有正确添加行
只需正确地添加值“Taras Feschuk”的答案中提到的值。
无论何时编写
c.moveToFirst()
。首先检查if(c.getCount()>0)
如果要帮助解决问题,您需要添加错误日志。正如您所看到的,即使没有这些信息,我们还是设法在您的程序中找到了两个bug(您是否看到由于@slukian注释而产生的编辑?),如果您想帮助您解决问题,您需要添加错误日志。正如您所看到的,即使没有这些信息,我们还是设法在您的程序中找到了两个bug(您是否看到了由于@slukian注释而产生的编辑?)还添加了一些代码片段的描述..这可以帮助更多:)我还可以建议将表名和列名存储在类的私有变量中。它将创建更灵活的方式来对数据库进行任何将来的更改,并编写选择/更新/删除/插入逻辑。还可以使用代码段添加一些说明..这可以帮助更多:)我还可以建议将表名和列名存储在类的私有变量中。它将创建更灵活的方式来对数据库进行任何将来的更改,并编写选择/更新/删除/插入逻辑。