title: When should I close an SQLiteDatabase object?
body: <p>I kept getting this annoying runtime error for hours, which crashed my app:</p>
  
  <blockquote>
    <p>java.lang.RuntimeException: An error occured while executing
    doInBackground().</p>
    
    <p>Caused by: java.lang.IllegalStateException: attempt
    to re-open an already-closed object: SQLiteDatabase</p>
  </blockquote>
  
  <p>After some debugging I found that it happens because I close my SQLiteDatabse object, in the <code>onDestory()</code> method. It happens when I call <code>SQLiteOpenHelper.close()</code> as well.</p>
  
  <pre><code>@Override
  protected void onDestroy() {
      super.onDestroy();
      _cursor.close(); //is fine
      _db.close(); //causes error
      _databaseHelper.close(); //causes error too (probably calls db.close() internally..?)
      SharedFunctions.d("closed!"); //ignore this ugly thing
  }
  </code></pre>
  
  <p>This brings up the two questions</p>
  
  <ol>
  <li>Am I doing it right? (probably not)</li>
  <li>When <em>do I</em> need to close a SQLiteDatabase object, if not in the <code>onDestroy</code> method?</li>
  </ol>
  
  <p>Edit:
  The DB and the Helper classes are static:</p>
  
  <pre><code>public class MainActivity extends Activity {
  
      private Cursor _cursor = null;
      private MyCursorAdapter _myCursorAdapter = null;
      private ListView _listView = null;
  
      private static SalaryDatabaseHelper _databaseHelper = null;
      public static SQLiteDatabase db = null;
  
      ...
  </code></pre>
  
  <p>I initialize _databaseHelper in the onCreate() method:</p>
  
  <pre><code>//get database helper
          if(_databaseHelper == null)
              _databaseHelper = SalaryDatabaseHelper.getInstance(this);
  </code></pre>
  
  <p><code>db</code> is initialized in an <code>AsyncTask.doInBackground()</code>:</p>
  
  <pre><code>protected Boolean doInBackground(Integer... data)
  {
      try {
          //get writable database
          if(db == null)
              db = SalaryDatabaseHelper.getDbInstance();
  </code></pre>
  
  <p>I use singletons for the helper class and the database class: (both accessed via the helper class)</p>
  
  <pre><code>class MyDatabaseHelper extends SQLiteOpenHelper{
  
      private static SalaryDatabaseHelper _instance = null;
      private static SQLiteDatabase _dbInstance = null;
  
      //singletons
      public static synchronized SalaryDatabaseHelper getInstance(Context context)
      {
          // Use the application context, which will ensure that you
          // don't accidentally leak an Activity's context.
          if (_instance == null)
              _instance = new SalaryDatabaseHelper(context.getApplicationContext());
  
          return _instance;
      }
  
      public static synchronized SQLiteDatabase getDbInstance() {
          if(_dbInstance == null)
              _dbInstance = _instance.getWritableDatabase();
  
          return _dbInstance;
      }
  
      ...
  </code></pre>