注册 | 登录

android - Usage CursorLoader without ContentProvider and avoiding database leaks

itPublisher 分享于



I have implemented the class found in this question:

Usage CursorLoader without ContentProvider

It is a means of using the LoaderManager and CursorLoader without a content resolver. I am using it to load data from a SQLite database and display it in a ListFragment.

The problem I am seeing is that the database is leaking. Obviously this is because I am not closing the database when I am done.

I have now started to do this, but I am concerned as the database could be accessed at any time by background tasks scheduled with the AlarmManager. I am worried that I might close the database when another class needs it open.

My solution has been to count the opens/closes and only close the database when no one is using it. Like so:

    public synchronized SQLiteDatabase openDataBase()

        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()

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

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

This appears to work, but it has meant adding an extra line of code all over my application. Furthermore I've had trouble with the LoaderManager not behaving as expected and it calls its reset function more than it does its load, so I've had to put this fix in:

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

        public Cursor loadInBackground()
            return JSQLite.getSingleton(getActivity()).retrieveTextsSent(mMode == 1 ? true : false);

        public void reset()
            if (mDBOpens > 0)


It feels like this isn't the correct way of doing it. Is there another, cleaner means of closing/opening the database only when needed?

Thanks, Jason.

android sqlite android-loadermanager android-cursorloader connection-leaks
  this question
asked Dec 30 '12 at 14:15 Demonofloom 125 2 15 1   "Obviously this is because I am not closing the database when I am done." -- A ContentProvider does not close its database ever, either. –  CommonsWare Dec 30 '12 at 14:19      Thanks, that is interesting to know. –  Demonofloom Dec 30 '12 at 15:40


Know someone who can answer? Share a link to this question via email, Google+, Twitter, or Facebook.








您的注册邮箱: 修改

重新发送激活邮件 进入我的邮箱