Страница 1 из 1

SQLiteOpenHelper singleton

Добавлено: 07 янв 2014, 01:26
rgnrok
Добрый вечер.
Делаю приложение которое в многопоточном режиме обращается к базе, следовательно каждый раз открывать/закрывать соединения с БД не представляется возможным, поэтому я использую "имитацию" singleton

Код: Выделить всё

public class HelperFactory {

    private static DatabaseHelper databaseHelper;

    public static DatabaseHelper getDbHelper() {
        return databaseHelper;
    }

    public static void setDbHelper(Context context) {
        databaseHelper = OpenHelperManager.getHelper(context,
                DatabaseHelper.class);
    }

    public static void releaseHelper() {
        if (databaseHelper != null) {
            OpenHelperManager.releaseHelper();
            databaseHelper = null;
        }
    }
}
Как видно на самом деле здесь используется ORMLite с его оболочкой OrmLiteSqliteOpenHelper, но по сути это просто обертка для SQLiteOpenHelper с готовым singleton.

С таким подходом все хорошо работает, база не лочится, ничего не падает, однако спустя недели разработки, меня окатило холодным потом, когда я понял что метод releaseHelper() я нигде не использую, а следовательно, для объекта SQLiteOpenHelper никогда не вызывается close()

На сайте ormlite рекомендуют закрывать соединение в onDestroy методе Activity, но это скорее вариант для приложения в котором всего одно Activity, у меня же их несколько, и во время уничтожения одного, вполне может происходить запись в базу в фоновом потоке.
Кто-то предлагает создавать подключение в onCreate() методе класса Application, и закрывать в onTerminate(), однако на девайсах последний метод никогда не вызывается.

Собственно вопрос: В какой момент необходимо закрывать соединение с базой? Можно ли его оставить открытым, на совесть самого Android?
Или может быть существуют другие способы получения доступа к базе в любой момент из любой точки приложения (не обязательно с использованием ORMLite)?

Спасибо, что дочитали до конца. :)

Re: SQLiteOpenHelper singleton

Добавлено: 07 янв 2014, 01:51
altwin
Учитывая синглтон - кто вам мешает реализовать закрытие базы в деструкторе(по java way -finalize())? Хоть и не рекомендован "деструктор" в java, но по моему это тот самый момент. Но в вашем случае код, который вы показали - это не синглтон, все что вы имеете - приватное поле, но у вас публичный конструктор и нет метода Initilizer -а == это вообще не рядом с синглтоном. А по сути - да объект не используется, он уничтожается и выполняется код "деструктора", хотя если честно - пишу от фонаря - не думал об этом и может быть есть камни под водой...

P.S. синглтон подразумевает, что у вас есть приватный объект этого класса, возвращаемый методом getInstance() и приватный конструктор класса, чтобы исключить доступ из вне.. Имея публичный конструктор синглтона не будет...

Re: SQLiteOpenHelper singleton

Добавлено: 07 янв 2014, 11:01
rgnrok
По поводу деструктора, спасибо, попробую.
Синглтон обеспечивает сам ORMLite

Код: Выделить всё

OpenHelperManager.getHelper(context, DatabaseHelper.class); 
У меня же получается оболочка которая вызывает создание экземпляра один раз при запуске приложения, и затем позволяет обращаться к хелперу без передачи context.
Но вы правы, такой "обход" синглтона может вылезти боком, надо будет его переделать.
Спасибо

Re: SQLiteOpenHelper singleton

Добавлено: 07 янв 2014, 15:02
Foenix
ваш подход бесперспективный, нужно использовать ContentProvider

Re: SQLiteOpenHelper singleton

Добавлено: 07 янв 2014, 15:09
altwin
rgnrok писал(а): Синглтон обеспечивает сам ORMLite
не обеспечивает он ничего, скорее некое подобие "фабричного" метода, я вот посмотрел на него, перед тем как за праздничный стол сесть - это вообще довольно странная библиотека если честно.

P.S. Счастливого Рождества! :D