Использование CursorLoader без ContentProvider и избежание утечек из базы данных.

Я реализовал класс, найденный в этом вопросе:

Использование CursorLoader без ContentProvider

Это средство использования LoaderManager и CursorLoader без распознавателя контента. Я использую его для загрузки данных из базы данных SQLite и отображения его в ListFragment.

Проблема, которую я вижу, состоит в том, что база данных протекает. Очевидно, это потому, что я не закрываю базу данных, когда я закончу.

Сейчас я начал это делать, но я обеспокоен тем, что база данных может быть доступна в любое время с помощью фоновых задач, запланированных с помощью AlarmManager. Я беспокоюсь, что могу закрыть базу данных, когда другой класс нуждается в ее открытии.

Мое решение состояло в том, чтобы считать открытия / закрытия и закрывать базу данных только тогда, когда ее никто не использует. Вот так:

    public synchronized SQLiteDatabase openDataBase()
{
    try
    {
        mDatabaseUsers++;

        Log.d(TAG, "DatabaseUsers: " + mDatabaseUsers);

        // If already open, return it.
        if (mOpenDatabase != null && mOpenDatabase.isOpen())
            return mOpenDatabase;

        OpenHelper openHelper = new OpenHelper(mContext);
        return openHelper.getWritableDatabase();
    } catch (SQLException e)
    {
        Log.e("MessageDelay", "Error opening database: " + e.toString());

        return null;
    }
}

public synchronized void closeDatabase()
{
    mDatabaseUsers--;

    // If no one is using the database, close it.
    if (mOpenDatabase != null && mDatabaseUsers == 0)
    {
        mOpenDatabase.close();
    }

    Log.d(TAG, "DatabaseUsers: " + mDatabaseUsers);
}

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

        return new SimpleCursorLoader(getActivity())
    {
        private int mDBOpens = 0;

        @Override
        public Cursor loadInBackground()
        {
            mDBOpens++;
            return JSQLite.getSingleton(getActivity()).retrieveTextsSent(mMode == 1 ? true : false);
        }

        @Override
        public void reset()
        {
            if (mDBOpens > 0)
            {
                JSQLite.getSingleton(getContext()).closeDatabase();
            }
            super.reset();

            mDBOpens--;
        }
    };

Такое ощущение, что это не правильный способ сделать это. Есть ли другое, более чистое средство закрытия / открытия базы данных только при необходимости?

Спасибо, Джейсон.

0 ответов

Другие вопросы по тегам