1

この質問にあるクラスを実装しました:

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--;
        }
    };

これは正しいやり方ではないように感じます。必要な場合にのみデータベースを閉じたり開いたりする別のよりクリーンな手段はありますか?

ありがとう、ジェイソン。

4

0 に答える 0