Как правильно открыть / закрыть SQLite db в Android
у меня есть приложение, которое работает правильно и не заставляет закрываться или сбой. Но когда я смотрю на LogCat, он иногда дает мне это:
05-20 15:24:55.338: E/SQLiteDatabase(12707): close() was never explicitly called on database '/data/data/com.---.--/databases/debt.db'
05-20 15:24:55.338: E/SQLiteDatabase(12707): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here
немного ниже...
05-20 15:24:55.338: E/System(12707): Uncaught exception thrown by finalizer
05-20 15:24:55.338: E/System(12707): java.lang.IllegalStateException: Don't have database lock!
Я не уверен, когда я должен открывать и закрывать свою базу данных?
у меня есть основное действие, которое является просто заставкой. Затем он переходит в действие, которое вызывает ListView, используя информацию из БД; так что это этой активность, где БД является первым открытый.
существует также одно другое действие, где требуется БД, которая ветвится от одного с ListVeew. Когда я должен открывать и закрывать это? Слово, кажется, что мне просто нужно открыть один раз, а затем закрыть, когда приложение "приостановлено", "остановлено" или "уничтожено".
Если это так, где я могу поместить db.метод close... в заставку главного экрана где то onStop и т. д. находится? или та же активность, что и при открытии БД? или.. есть другое место?
обновление:
это строка в коде, на которую указывает ошибка:
public void open() throws SQLException {
database = dbHelper.getWritableDatabase();
}
3 ответов
если вы используете экземпляр класса DatabaseHelper и после инициализации объекта DBHelper, каждый раз, когда вы работаете в базе данных, вы должны вызвать метод open перед работой, затем создать новый курсор, запросить базу данных, работать с информацией, которую вы только что сохранили в курсоре, когда вы закончите, закройте курсор, затем закройте базу данных. Например, если вы хотите захватить каждый элемент в базе данных, вы должны сделать что-то вроде :
...
DataBaseHelper db = new DataBaseHelper(this);
...
db.open();
Cursor cursor = db.getAllItems();
maxCount = cursor.getCount();
Random gen = new Random();
row = gen.nextInt(maxCount); // Generate random between 0 and max
if (cursor.moveToPosition(row)) {
String myString = cursor.getString(1); //here I want the second column
displayString(myString); //private method
}
cursor.close();
db.close();
getAllItems
- это публичный метод в моем DatabaseHelper
, это выглядит так, если вам интересно
public Cursor getAllItems() {
return db.query(DATABASE_TABLE,
new String[] {
KEY_ROWID,
KEY_NAME
},
null,
null,
null,
null,
null);
}
вот как я получаю доступ к своей базе данных, и я не получил ни одной из ошибок, которые у вас есть, и он отлично работает.
раньше я делал так, как @Shikima упоминалось выше, но в сложных приложениях, в которых есть много фоновых служб,многопоточность и т. д., Это может стать очень утомительным, когда вам нужно управлять многими экземплярами базы данных и, кроме того, открывать и закрывать их.
чтобы преодолеть это, я использовал следующий метод, и это, кажется, работает хорошо.
1.
объявить и инициализировать экземпляр YourDBHelperClass в вашей приложение базовый класс такой :
public class App extends Application {
public static YourDBHelperClass db;
@Override
public void onCreate() {
super.onCreate();
db = new YourDBHelperClass(getApplicationContext());
db.open();
}
}
2.
в вашей деятельности или в любом другом месте, где вы хотите использовать БД, инициализируйте объект YourDBHelperClass следующим образом:
YourDBHelperClass db = App.db;
и затем вы можете использовать базу данных в любом случае вы хотите, не беспокоясь об открытии и закрытии его вручную каждый раз. The SQLiteOpenHelper заботится о закрытии, когда приложение уничтожается
вероятно, вы неправильно обрабатываете свою базу данных; вы открываете больше экземпляров базы данных, чем закрываете.
есть несколько шаблонов проектирования, которые вы можете следовать, чтобы исправить это поведение. Возможно, вы захотите проконсультироваться ответ для получения дополнительной информации.