java - 为什么我无法在 Android 的 SQLite 数据库中添加这些默认值?

标签 java android debugging android-sqlite default-value

所以我正在构建一个警报应用程序。我想在首次安装应用程序时显示一些默认警报。例如,上午 7 点、上午 8 点和上午 9 点有 3 个闹钟。下面是我的代码。

调用

getAllAlarms() 来检索要显示的警报列表。第一次加载时,数据库将为空,因此我想插入一些默认值(如果是这种情况)。这可以在 else 语句中看到,我在其中添加警报,然后对其自身进行递归调用。我的理解是,添加3个闹钟后,我再次调用getAllAlarms,它应该正常进入if语句。从调试 System.out.println 语句中可以看出,情况确实如此。警报列表按预期打印出来,但是,在该行的某个地方似乎再次调用了该方法,这导致列表被清空,如最后的调试语句中所示。

你能看出问题出在哪里吗?我已经在项目中进行了文件搜索,并且除了方法本身和 ListActivity 内部之外,我没有在任何地方调用删除方法,也没有调用 getAllAlarms。我认为问题必须集中在 getAllAlarms 方法中,但我找不到它。是递归调用吗?

   // Getting All Alarms
public List<Alarm> getAllAlarms() {
    List<Alarm> alarmList = new ArrayList<Alarm>();
    // Select All Query
    String selectQuery = "SELECT  * FROM " + TABLE_ALARMS;

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

    // looping through all rows and adding to list
    if (cursor.moveToFirst()) {
        do {
            Alarm alarm = new Alarm();
            alarm.setID(cursor.getInt(0));
            alarm.setHour(cursor.getInt(1));
            alarm.setMinutes(cursor.getInt(2));
            // Adding alarm to list
            alarmList.add(alarm);
            System.out.println("inside loop");
            System.out.println(alarmList);

        } while (cursor.moveToNext());
    }
    else
    {           
        System.out.println("Adding default values...");
        addAlarm(new Alarm(7,0));
        addAlarm(new Alarm(8,0));
        addAlarm(new Alarm(9,0));
        System.out.println("Finished adding default values...");
        getAllAlarms();
    }

    System.out.println("before");
    System.out.println(alarmList);
    System.out.println("after");
    // return alarm list
    return alarmList;
}

这是我的添加方法:

void addAlarm(Alarm alarm) {
    SQLiteDatabase db = this.getWritableDatabase();

    ContentValues values = new ContentValues();
    values.put(KEY_HOUR, alarm.getHour()); // Alarm Name
    values.put(KEY_MINUTES, alarm.getMinutes()); // Alarm Phone

    // Inserting Row
    db.insert(TABLE_ALARMS, null, values);
    db.close(); // Closing database connection
}

调试输出:

04-23 16:17:49.261: I/System.out(10938): Adding default values...
04-23 16:17:49.291: I/System.out(10938): Finished adding default values...
04-23 16:17:49.291: I/System.out(10938): inside loop
04-23 16:17:49.291: I/System.out(10938): [07:00]
04-23 16:17:49.296: I/System.out(10938): inside loop
04-23 16:17:49.296: I/System.out(10938): [07:00, 08:00]
04-23 16:17:49.296: I/System.out(10938): inside loop
04-23 16:17:49.296: I/System.out(10938): [07:00, 08:00, 09:00]
04-23 16:17:49.296: I/System.out(10938): before
04-23 16:17:49.296: I/System.out(10938): [07:00, 08:00, 09:00]
04-23 16:17:49.296: I/System.out(10938): after
04-23 16:17:49.296: I/System.out(10938): before
04-23 16:17:49.296: I/System.out(10938): []
04-23 16:17:49.296: I/System.out(10938): after

更新::

我已经尝试过,但没有成功:

if (cursor.moveToFirst()) { 做 { 警报alarm = new Alarm(); Alarm.setID(cursor.getInt(0)); Alarm.setHour(cursor.getInt(1)); Alarm.setMinutes(cursor.getInt(2)); //将警报添加到列表中 AlarmList.add(警报); System.out.println("内部循环"); System.out.println(alarmList);

    } while (cursor.moveToNext());            
}
else
{           
    System.out.println("Adding default values...");
    addAlarm(new Alarm(7,0));
    addAlarm(new Alarm(8,0));
    addAlarm(new Alarm(9,0));
    System.out.println("Finished adding default values...");
}

if(alarmList.isEmpty() || alarmList == null)
{
    System.out.println("test"  + alarmList);
    getAllAlarms();
}

但是,如果我删除 if 语句来检查空列表,然后将检查添加到数据库外部和 ListActivity 内部,则此操作会自行起作用。但这不是我想要的。我不想在数据库类之外处理默认值插入。

其他 {
System.out.println("添加默认值..."); addAlarm(新警报(7,0)); addAlarm(新警报(8,0)); addAlarm(新警报(9,0)); System.out.println("默认值添加完成..."); }

以及ListActivity内部:

protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_alarm_list);

Database db = new Database(AlarmListActivity.this);
list = db.getAllAlarms();
if(list.isEmpty())
{
    list = db.getAllAlarms();
}
....
....

}

最佳答案

正如@umesh建议的那样,使用 getReadableDatabase(),不需要 db.close(),但最重要的是将您的写入包装在事务中:

db.beginTransaction();
// insert
db.setTransactionSuccessful();
db.endTransaction();

更新:单例(ish)模式

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DBOpenHelper extends SQLiteOpenHelper {

    private enum OpenHelperEnum {
        INSTANCE; // Singleton instance;

        // Instance of dbHelper for all DB access in threads
        private SQLiteOpenHelper dbHelper = null;
        private SQLiteDatabase database = null;

        public SQLiteDatabase getDB(final Context context) {
            if (dbHelper == null) {
                dbHelper = new DBOpenHelper(context);
            }
            if (database == null) {
                database = dbHelper.getReadableDatabase();
            }
            return database;
        }
    }

    public DBOpenHelper(final Context context) {
        super(context, "DBName", null, 1);
    }

    @Override
    public void onCreate(final SQLiteDatabase database) {
        // ...
    }

    @Override
    public void onUpgrade(final SQLiteDatabase database, final int oldVersion, final int newVersion) {
        // ...
    }

    @Override
    public void onDowngrade(final SQLiteDatabase database, final int oldVersion, final int newVersion) {
        // ...
    }

    public static SQLiteDatabase getDB(final Context context) {
        return DBOpenHelper.OpenHelperEnum.INSTANCE.getDB(context);
    }
}

要获取数据库,请使用:

final SQLiteDatabase db = DBOpenHelper.getDB(this);

关于java - 为什么我无法在 Android 的 SQLite 数据库中添加这些默认值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16173196/

相关文章:

java - 使用文件名作为 FileReader 的输入

java - AppEngine 突然出现 503 错误

android - 查看持有者 OnClickListener 事件问题

android - 如何从 3G 和 2G/EDGE 反之切换?

linux - 我可以指示 gdb 运行命令以响应 SIGTRAP 吗?

java - 线程执行指定的时间。

java - 将文本添加到 JTextArea 时出现问题( append 或设置文本)

android - 为什么 MapFragment(HERE-API) 扩展了 android.app.Fragment 而不是 android.support.v4.app.Fragment?

debugging - 安装 WinDBG

c# - 无法找到或打开 PDB 文件,正在调试 native 代码