この質問にあるクラスを実装しました:
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--;
}
};
これは正しいやり方ではないように感じます。必要な場合にのみデータベースを閉じたり開いたりする別のよりクリーンな手段はありますか?
ありがとう、ジェイソン。