Android SQLite Database Management

Just as I was trying to wrap up Score It! I noticed my Logcat window was getting flooded with error messages. Somehow during all my debugging and development I didn’t notice the pages of errors being thrown by SQLite.

java.lang.IllegalStateException ... SQLiteDatabase created and never closed

Now these errors didn’t appear to have any adverse affects on my application but I certainly did not want to release an app that I knew was spewing errors. I wrestled with this for an evening searching and trying everything I could think of.

Some people suggested opening and closing the database around all accesses. Others suggested littering all of the lifecycle overrides with open and close statements. I found the former unreasonable and the latter inadequate. I needed to keep my database connections open as much as possible because I was working with ListView and ListActivity objects.

I managed to reduce the frequency of the errors but it was still happening consistently if I followed specific steps but I decided to throw in the towel for the time being.

The next day I decided to revisit the issue and make sure I had a better understanding of the problem. I stepped through my app, using a ridiculous number of breakpoints. It soon became clear that it was not a specific line of code that was causing the problem. This error was being generated by the database object when the garbage collector was hitting it.

I experimented a bit further and came up with a solution that seemed to eliminate all of my SQLite database errors.

In the Activities that maintained a database connection I put a close() statement in the Activity.OnDestroy() override:

1
2
3
4
5
 @Override
  protected void onDestroy() {
      super.onDestroy();
      mDbHelper.close();
  }

In my database helper class, modeled after Notepad, I changed the open function from:

1
2
3
4
5
6
    public ScoreDbAdapter open() throws SQLException {
      mDbHelper = new DatabaseHelper(mCtx);
      mDb = mDbHelper.getWritableDatabase();

        return this;
    }

To the following:

1
2
3
4
5
6
7
8
    public ScoreDbAdapter open() throws SQLException {
      if (mDbHelper == null) {
          mDbHelper = new DatabaseHelper(mCtx);
      }
      mDb = mDbHelper.getWritableDatabase();

        return this;
    }

This cleared up all the errors.

Copyright © 2013 Thomas Holmes