Как правильно открыть / закрыть 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 заботится о закрытии, когда приложение уничтожается


вероятно, вы неправильно обрабатываете свою базу данных; вы открываете больше экземпляров базы данных, чем закрываете.

есть несколько шаблонов проектирования, которые вы можете следовать, чтобы исправить это поведение. Возможно, вы захотите проконсультироваться ответ для получения дополнительной информации.