我已经实现了在这个问题中找到的类:
没有 ContentProvider 的 CursorLoader 使用
它是一种在没有内容解析器的情况下使用 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--;
}
};
感觉这不是正确的做法。是否有另一种更简洁的方法来仅在需要时关闭/打开数据库?
谢谢,杰森。