Использование 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--;
}
};
Такое ощущение, что это не правильный способ сделать это. Есть ли другое, более чистое средство закрытия / открытия базы данных только при необходимости?
Спасибо, Джейсон.