title: android SQLiteOpenHelper and Leaks
body: <p>I wanna make SQLiteOpenHelper with some additional methods (like getStreetsCursor) which returns data from my db. So i wrote something like this:</p>
  
  <pre><code>public class DBHelper extends SQLiteOpenHelper { 
      public static final String DB_NAME="some.db"; 
      public static final String T1_NAME="streets"; 
      public static final String T1_FNAME1="name"; 
      public static final String T2_NAME="addresses"; 
      public static final String T2_FNAME1="name"; 
      public static final String T2_FNAME2="address"; 
  
      private Context appContext;
  
    public DBHelper(Context context) { 
      super(context, DB_NAME, null, 1);
      appContext=context;
    }
  
    public Cursor getStreetsCursor(String chars) {
    SQLiteDatabase dbReadable=this.getReadableDatabase();
        Cursor curStreets = dbReadable.query(DBHelper.T1_NAME, 
                  new String[] {"_id",DBHelper.T1_FNAME1}, 
                  DBHelper.T1_FNAME1+" LIKE(\""+chars.toUpperCase()+"%\")",
                  null, null, null, DBHelper.T1_FNAME1);
  
      return curStreets;
    }
  </code></pre>
  
  <p>There are several methods like getStreetsCursor (getAddresses, getAddress4 etc) defined in DBHelper.
  I guess if it is a DB <strong>Helper</strong> it definitely should have such methods i mean the DBHelper is a logical placeholder for them.</p>
  
  <p>What i do in the activity is create a new DBHelper instance and store it in private field (called mDBHelper) of activity. Additionally in onDestroy method of activity i have mDBHelper.close().</p>
  
  <pre><code>private DBHelper mDBHelper;
  
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          mDBHelper = new DBHelper(this);
  ...
      @Override
      protected void onDestroy() {
          if (mDBHelper!=null){
              mDBHelper.close();
              Log.i(APP_TAG,"mDBHelper.close() in "+this.getClass());
          }
          super.onDestroy();
      }
  </code></pre>
  
  <p>Those activities uses the mDBHelper only in one way - by calling it's custom methods like mDBHelper.getStreetsCursor(). 
  Eventually I found an exception message in logcat about my app got leaks in such activities which uses DBHelper. It says something like "database was never closed". So i decided to add a call to close() method in each of my custom methods just before return. So it looks like:</p>
  
  <pre><code>      public Cursor getStreetsCursor(String chars) {
            SQLiteDatabase dbReadable=this.getReadableDatabase();
            Cursor curStreets = dbReadable.query(DBHelper.T1_NAME, 
                      new String[] {"_id",DBHelper.T1_FNAME1}, 
                      DBHelper.T1_FNAME1+" LIKE(\""+chars.toUpperCase()+"%\")",
                      null, null, null, DBHelper.T1_FNAME1);
  
              dbReadable.close();
              return curStreets;
        }
  </code></pre>
  
  <p>Now i got no leaks but got the next problem - only first call to mDBHelper.getStreetsCursor() really executes. All of the next calls returns null. Thats due to dbReadable.close(); line. If i remove it everythig works fine but i got leaks again.
  So i cant figure out whats going wrong. In every custom method i got SQLiteDatabase dbReadable=this.getReadableDatabase(); line which should return a readable instance but after executing the close() method it doesn't.
  I guess its about my custom methods because they calls .getReadableDatabase() inside an instance of DBHelper. If i place those methods directly in activity everything works fine - no leak exceptions and every time methods returns a proper data. But i want to place those methods in my DBHelper class. </p>
  
  <p>So the main question is - what's wrong and how to do that properly?</p>