Совместное использование базы данных sqlite между несколькими операциями Android

Могут ли две или более операции Android открыть базу данных sqlite3 для записи?

У меня есть два вида деятельности, которые необходимо вставить данные в одну базу данных sqlite. При втором SQLiteOpenHelper.getWriteableDatabase()вызове Activity генерируется исключение IllegalStateException с сообщением « База данных SQLite создана и никогда не закрывается ».

Мне удалось избежать исключения, сделав объект моей базы данных одиночным, но я думаю, что должен быть лучший способ.

Спасибо,

Джон

12.10.2009 21:03:53
Вы можете закрыть БД после того, как написали в нее ..
svens 12.10.2009 21:11:09
Я тоже думал об этом, но одним действием является ListActivity, который заполняется с помощью адаптера Cursor. Я думал, что закрытие базы данных приведет к сбою запроса адаптера.
John in MD 12.10.2009 21:19:47
@John: если вы используете одноэлементную базу данных, где вы ее открываете и закрываете?
emeraldhieu 17.08.2011 18:50:01
Когда это необходимо, я открываю базу данных, делаю что угодно, затем закрываю.
John in MD 19.08.2011 14:48:20
3 ОТВЕТА
РЕШЕНИЕ

На самом деле никогда не может быть запущено более одного занятия одновременно. Самый простой способ исправить это - закрыть первое действие перед началом второго действия. Вы можете сделать это в onPause (), а затем снова открыть его в onResume (). Примерно так (очень псевдо-код):

MyActivity {
    OnResume()
        open connection to database
    OnPause()
        close connection to database
}

Таким образом, вы никогда не пытаетесь использовать более одного соединения одновременно, и соединение всегда доступно.

13
12.10.2009 23:19:08
Мне было интересно, если этот подход лучше, чем когда действия используют один и тот же объект-одиночка. Я думаю, это потому, что этот подход оставляет соединение в правильном состоянии при приостановке действия. Наличие одноэлементного соединения делает проблематичной очистку. Спасибо.
John in MD 16.10.2009 16:45:52
Да ... если вы не закрываете его в onPause, тогда соединение просто обрывается, если (например) вы получаете телефонный звонок.
Jeremy Logan 16.10.2009 23:51:07
Это не работает. Я получаю InvalidStateException и SQL-запрос, который не удалось выполнить, даже до вызова onResume (). Android, кажется, запрашивает курсоры до вызова onResume ().
cdonner 1.07.2010 01:36:48
Я успешно использую этот шаблон в полдюжине приложений. Если у вас есть проблемы с этим, вы должны делать что-то смешное. Задайте вопрос и почтовый индекс.
Jeremy Logan 13.07.2010 06:27:44
@peno: Итак, вы говорите, что мое предложение решить конкретную проблему не решит совершенно другую проблему? Представь это.
Jeremy Logan 18.05.2012 20:46:16

У меня также есть несколько действий, и каждое действие открывает свое собственное соединение с базой данных. Я поддерживаю основное действие в то время, когда начинаю другие действия, и вызываю метод finish () для дочерних действий, когда они мне больше не нужны.

Я вижу, что дочерний Activity может успешно открыть соединение и запросить данные, пока основной Actitity все еще удерживает свой DBAdapter. Когда дочернее действие заканчивается, основное действие запрашивает все открытые курсоры. Кажется, это происходит автоматически.

Тем не менее, после некоторого нажатия на пользовательский интерфейс, который приводит к тому, что мое приложение запускается и завершает действия, я в конечном итоге получу исключение:

ERROR/Database(17657): Leak found
ERROR/Database(17657): java.lang.IllegalStateException:
      /data/data/yourpackage/databases/yourdatabase 
      SQLiteDatabase created and never closed
ERROR/Database(17657): at android.database.sqlite.SQLiteDatabase.<init>
     (SQLiteDatabase.java:1694)

Исключением является не действие, которое в настоящее время находится на переднем плане, а то, что было завершено некоторое время назад. Итак, происходит то, что сборщик мусора очищает и находит соединение с открытой базой данных. Это не влияет на приложение - оно продолжает работать нормально, и все запросы из переднего плана Activity возвращают данные.

Решение состоит в том, чтобы просто закрыть соединение в дочерней активности. Событие onDestroy () является подходящим местом для этого:

@Override    
protected void onDestroy() {        
    super.onDestroy();
    myAdapter.close();
}

Поскольку я добавляю это во все свои детские занятия, я больше не получаю исключения.

2
1.07.2010 02:13:27

Что бы я сделал, это определил базу данных в суперклассе, который является AppCompatActivity, если все действия расширяют этот класс, или определил его в классе Activity, который наследуется для всех действий.

0
29.01.2018 13:37:34