Я пытаюсь вставить строки в базу данных SQLite в Android. Вызов для вставки записи в мою БД выглядит так: DataHelper.insertChild (context, child). Моя цель - обернуть функциональность в статически называемые функции, которые обрабатывают все мелочи. Сначала позвольте мне поделиться с вами своим кодом.
Я делаю это с помощью статических методов:
private static SQLiteDatabase prepareChildDatabase(Context context) {
Log.d(TAG, "DB: prepareChildDatabase");
OpenHelper openHelper = new OpenHelper(context);
return openHelper.getWritableDatabase();
}
Тогда я делаю свою вставку:
public static long insertChild(Context context, Child child) {
Log.d(TAG, "DB: insertChild");
SQLiteDatabase db = prepareChildDatabase(context);
SQLiteStatement insertStmt = db.compileStatement(INSERT);
insertStmt.bindLong(1, child.getBirthday().getTime());
// These are optional
if(child.getName() != null) {
insertStmt.bindString(2, child.getName());
} else {
insertStmt.bindNull(2);
}
if(child.getPhoto() != null) {
String photoUri = child.getPhoto().toString();
insertStmt.bindString(3, photoUri);
} else {
insertStmt.bindNull(3);
}
final long id = insertStmt.executeInsert();
// insertStmt.clearBindings(); // Not sure this is necessary
insertStmt.close();
db.close();
return id;
}
Для справок, мой OpenHelper здесь:
private static class OpenHelper extends SQLiteOpenHelper {
OpenHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
Log.d(TAG, "DB: OpenHelper: onCreate: " + CREATE_CHILDREN_TABLE);
db.execSQL(CREATE_CHILDREN_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
}
И, наконец, переменные, операторы и таблица:
private static final String TABLE_NAME = "children";
private static final String COL_NAME = "name";
private static final String COL_BDAY = "birthday";
private static final String COL_PHOTO = "photo";
private static final String INSERT = "insert into "
+ TABLE_NAME + " ("
+ COL_BDAY + ", "
+ COL_NAME + ", "
+ COL_PHOTO + ") values (?, ?, ?)";
private static final String UPDATE = "update "
+ TABLE_NAME + "set "
+ COL_BDAY + " = ?, "
+ COL_NAME + " = ?, "
+ COL_PHOTO + " = ?) WHERE "
+ BaseColumns._ID + " = ?";
private static final String CREATE_CHILDREN_TABLE =
"CREATE TABLE " + TABLE_NAME + " ("
+ BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ COL_BDAY + " INTEGER NOT NULL, "
+ COL_NAME + " TEXT NULL, "
+ COL_PHOTO + " TEXT NULL)";
Так что происходит, когда я первый раз так называю, все работает нормально. Вставка работает, данные есть, и я могу экспортировать БД с устройства в мой браузер SQLite. Последующие вызовы insertChild (...) нарушают работу БД. Открытие не работает, так как SQLiteBrowser не показывает таблиц или строк, а открытие его в текстовом редакторе показывает некоторые вещи; Я предполагаю, что БД повреждена. Больше строк не вставляется, и я не могу прочитать это. Никаких ошибок не выдается.
Я предполагаю, что здесь происходит одна из двух вещей. Во-первых, мои дескрипторы не открываются / закрываются правильно, и некоторые ссылки где-то блокируются последующими вызовами. Во-вторых, мое понимание подготовленных утверждений неверно. Дело в том, что я смотрю на код, и он кажется нормальным. Откройте базу данных, свяжите с подготовленным оператором, выполните, закройте оператор, закройте базу данных.
Кто-нибудь готов помочь мне с этим? Я регистрируюсь, ищу исключения и пробую что-то, но ничего не получается. Думаю, я просто пропустил небольшую деталь. Это или я схожу с ума.
Спасибо
Mike
Обновление
Я обратил свое внимание на потоки, потому что проблема не воспроизводится на моем эмуляторе. Проверьте эти ссылки:
http://www.kagii.com/journal/2010/9/10/android-sqlite-locking.html
Приложение Android sqlite принудительно закрывается на устройстве
Каковы лучшие практики для SQLite на Android?