如何在Android中正确使用数据库?
我正在构建一个严重依赖数据库使用的应用程序。然而,我的模拟器运行不稳定,我找不到任何模式来说明什么/什么时候工作,什么/什么时候不工作 下面是我的适配器和助手类,直接取自我在web上找到的一个示例。在这种形式下,它可以完美地运行,可以添加记录、删除记录、更新记录并完美地显示在列表中 如果我尝试更改任何内容(例如KEY_TITLE值),即使我创建了一个全新的模拟器,应用程序也会崩溃。我完全被这件事难住了,任何帮助都会受到极大的欢迎如何在Android中正确使用数据库?,android,database,sqlite,emulation,adapter,Android,Database,Sqlite,Emulation,Adapter,我正在构建一个严重依赖数据库使用的应用程序。然而,我的模拟器运行不稳定,我找不到任何模式来说明什么/什么时候工作,什么/什么时候不工作 下面是我的适配器和助手类,直接取自我在web上找到的一个示例。在这种形式下,它可以完美地运行,可以添加记录、删除记录、更新记录并完美地显示在列表中 如果我尝试更改任何内容(例如KEY_TITLE值),即使我创建了一个全新的模拟器,应用程序也会崩溃。我完全被这件事难住了,任何帮助都会受到极大的欢迎 public class PirelliDBAdapter { p
public class PirelliDBAdapter {
private static final String DATABASE_NAME="data";
private static final String DATABASE_TABLE="reminders";
private static final int DATABASE_VERSION=1;
public static final String KEY_TITLE="title";
public static final String KEY_BODY="body";
public static final String KEY_LOCATION = "location";
public static final String KEY_TYPE = "type";
public static final String KEY_DATE_TIME="date_time_value";
public static final String KEY_ROW_ID="_id";
private DatabaseHelper mDbHelper;
private SQLiteDatabase db;
private static final String DATABASE_CREATE =
"create table " + DATABASE_TABLE + " ( "+
KEY_ROW_ID+ " integer primary key autoincrement, "+
KEY_TITLE+ " text not null, "+
KEY_BODY+" text not null, "+
KEY_DATE_TIME+ " text not null);";
private Context mContext;
public PirelliDBAdapter(Context c){
mContext=c;
}
// database open/close actions
public PirelliDBAdapter open() throws android.database.SQLException{
mDbHelper=new DatabaseHelper(mContext);
db=mDbHelper.getWritableDatabase();
return this;
}
public void close(){
mDbHelper.close();
}
// database CRUD operation
public long createReminder(String title, String body, String dateTime){
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_TITLE, title);
initialValues.put(KEY_BODY, body);
initialValues.put(KEY_DATE_TIME, dateTime);
return db.insert(DATABASE_TABLE, null, initialValues);
}
public boolean deleteReminder(long rowId){
return db.delete(DATABASE_TABLE, KEY_ROW_ID+" = "+rowId,null) >0;
}
public Cursor fetchAllReminders(){
return db.query(DATABASE_TABLE,new String [] {KEY_ROW_ID,KEY_TITLE,KEY_BODY,KEY_DATE_TIME}, null, null, null, null, null);
}
public Cursor fetchReminder(long rowId) throws SQLException{
Cursor c = db.query(true, DATABASE_TABLE, new String []{KEY_ROW_ID,KEY_TITLE,KEY_BODY,KEY_DATE_TIME}, KEY_ROW_ID+" = "+rowId, null,null,null,null,null);
if(c!=null){
c.moveToFirst();
}
return c;
}
public boolean updateReminder(long rowId, String title, String body, String dateTime){
ContentValues args = new ContentValues();
args.put(KEY_TITLE, title);
args.put(KEY_BODY, body);
args.put(KEY_DATE_TIME, dateTime);
return db.update(DATABASE_TABLE, args, KEY_ROW_ID+" = "+rowId, null)>0;
}
private static class DatabaseHelper extends SQLiteOpenHelper{
public DatabaseHelper(Context c){
// create the current database
super(c,DATABASE_NAME,null,DATABASE_VERSION);
}
// overrides
@Override
public void onCreate(SQLiteDatabase db) {
// create the database table
db.execSQL(DATABASE_CREATE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("drop table " + DATABASE_TABLE);
db.execSQL(DATABASE_CREATE);
}
}
以下是我在尝试向数据库添加另一个字段时的错误日志(在创建一个全新的AVD之后):
您是否正在仿真器上安装以前的版本?数据库只创建一次。在此之后,如果更改列名,它将不起作用
如果更改了数据库结构,则需要从设备/仿真器中清除应用程序以强制重新安装,或者增加版本号。当然,如果您更新了版本号,您需要实现
onUpgrade
来销毁数据库并重新创建(或执行适当的迁移)。您是否在emulator上的先前安装上进行了安装?数据库只创建一次。在此之后,如果更改列名,它将不起作用
如果更改了数据库结构,则需要从设备/仿真器中清除应用程序以强制重新安装,或者增加版本号。当然,如果更新版本号,则需要实现
onUpgrade
来销毁数据库并重新创建(或执行适当的迁移)。我必须更改适配器类,因此每当我更改数据库时,我都会使用下面的注释行:
public DatabaseHelper(Context c){
// create the current database
super(c,DATABASE_NAME,null,DATABASE_VERSION);
SQLiteDatabase db = this.getWritableDatabase();
try{//USE THESE WHEN CHANGING DB STRUCTURE
//db.execSQL("drop table if exists " + DATABASE_TABLE);
//db.execSQL(DATABASE_CREATE);
} catch( Exception E ){
Log.v("ERRRRRRROR", E.getMessage());
}
}
我必须更改适配器类,因此每当我更改数据库时,我都会使用下面的注释行:
public DatabaseHelper(Context c){
// create the current database
super(c,DATABASE_NAME,null,DATABASE_VERSION);
SQLiteDatabase db = this.getWritableDatabase();
try{//USE THESE WHEN CHANGING DB STRUCTURE
//db.execSQL("drop table if exists " + DATABASE_TABLE);
//db.execSQL(DATABASE_CREATE);
} catch( Exception E ){
Log.v("ERRRRRRROR", E.getMessage());
}
}
我正在为每一次更改创建一个新的AVD,但它仍然崩溃。。。在执行其他操作之前,如果数据库存在,是否有任何方法可以完全删除它?您可以转到应用程序的databases文件夹并手动删除它,例如通过file explorer。因此,无法通过编程方式执行此操作…?您也可以在终端中运行
adb-e uninstall com.your.application
,以删除它来自模拟器的应用程序(假设您已将终端设置为使用Android设备桥)。您将标题更改为什么?您可以在访问数据库帮助程序之前搜索数据库并删除物理文件。您还可以使用类似“db.execSQL”(“drop table”+database_table);”的命令,在升级过程中增加版本号并销毁数据库然后重新创建表格。我正在为每次更改创建一个新的AVD,但它仍然崩溃。。。在执行其他操作之前,如果数据库存在,是否有任何方法可以完全删除它?您可以转到应用程序的databases文件夹并手动删除它,例如通过file explorer。因此,无法通过编程方式执行此操作…?您也可以在终端中运行adb-e uninstall com.your.application
,以删除它来自模拟器的应用程序(假设您已将终端设置为使用Android设备桥)。您将标题更改为什么?您可以在访问数据库帮助程序之前搜索数据库并删除物理文件。您还可以使用类似“db.execSQL”(“drop table”+database_table);”的命令,在升级过程中增加版本号并销毁数据库然后重新创建表。如果您不粘贴崩溃日志,我们将无法提供任何帮助。我已在上面添加了错误日志。日志似乎不完整,您在开始时遗漏了一些行。引发了哪种类型的异常?请发布完整的错误,从一开始(以异常类型开始)我就重新发布了错误日志。希望我现在没有错过任何东西…你的帖子是不变的,即使它在1分钟前被编辑过。在pastebin(如pastebin.com)上发布大部分日志,并发布链接如果您不粘贴崩溃日志,我们将无法提供任何帮助。我已在上面添加了错误日志。日志似乎不完整,您在开头遗漏了一些行。引发了哪种类型的异常?请发布完整的错误,从一开始(以异常类型开始)我就重新发布了错误日志。希望我现在没有错过任何东西…你的帖子是不变的,即使它在1分钟前被编辑过。在pastebin.com等pastebin上发布更大部分的日志,并发布链接