title: Android sqlite getdatabase called recursively
body: <p>I have got a problem with my database.
  When the app start it should create the database with the tables if they not exist, but the app chrashes instantly after start. When i close the db after opening logcat tells me that "i want to open an already closed object" and when I do not close the database I have got the error  "<code>getReadableDatabase called recursively</code>". I do not know what I should do. Sometimes it works but when I unistall the app and install them again the errors apear.</p>
  
  <p>The error without the close:</p>
  
  <pre><code>02-20 11:50:06.980: E/AndroidRuntime(15375): FATAL EXCEPTION: main
  02-20 11:50:06.980: E/AndroidRuntime(15375): java.lang.RuntimeException: Unable to start activity ComponentInfo{de.vertretungsplan2/de.vertretungsplan2.Main}: java.lang.IllegalStateException: getDatabase called recursively
  02-20 11:50:06.980: E/AndroidRuntime(15375):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2339)
  02-20 11:50:06.980: E/AndroidRuntime(15375):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2389)
  02-20 11:50:06.980: E/AndroidRuntime(15375):    at android.app.ActivityThread.access$600(ActivityThread.java:153)
  02-20 11:50:06.980: E/AndroidRuntime(15375):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1269)
  02-20 11:50:06.980: E/AndroidRuntime(15375):    at android.os.Handler.dispatchMessage(Handler.java:99)
  02-20 11:50:06.980: E/AndroidRuntime(15375):    at android.os.Looper.loop(Looper.java:137)
  02-20 11:50:06.980: E/AndroidRuntime(15375):    at android.app.ActivityThread.main(ActivityThread.java:5289)
  02-20 11:50:06.980: E/AndroidRuntime(15375):    at java.lang.reflect.Method.invokeNative(Native Method)
  02-20 11:50:06.980: E/AndroidRuntime(15375):    at java.lang.reflect.Method.invoke(Method.java:525)
  02-20 11:50:06.980: E/AndroidRuntime(15375):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:739)
  02-20 11:50:06.980: E/AndroidRuntime(15375):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:555)
  02-20 11:50:06.980: E/AndroidRuntime(15375):    at dalvik.system.NativeStart.main(Native Method)
  02-20 11:50:06.980: E/AndroidRuntime(15375): Caused by: java.lang.IllegalStateException: getDatabase called recursively
  02-20 11:50:06.980: E/AndroidRuntime(15375):    at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:204)
  02-20 11:50:06.980: E/AndroidRuntime(15375):    at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:164)
  02-20 11:50:06.980: E/AndroidRuntime(15375):    at de.vertretungsplan2.helper.DBHandler.insertPW(DBHandler.java:89)
  02-20 11:50:06.980: E/AndroidRuntime(15375):    at de.vertretungsplan2.helper.DBHandler.onCreate(DBHandler.java:46)
  02-20 11:50:06.980: E/AndroidRuntime(15375):    at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:252)
  02-20 11:50:06.980: E/AndroidRuntime(15375):    at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:164)
  02-20 11:50:06.980: E/AndroidRuntime(15375):    at de.vertretungsplan2.Main.onCreate(Main.java:42)
  02-20 11:50:06.980: E/AndroidRuntime(15375):    at android.app.Activity.performCreate(Activity.java:5133)
  02-20 11:50:06.980: E/AndroidRuntime(15375):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
  02-20 11:50:06.980: E/AndroidRuntime(15375):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2293)
  02-20 11:50:06.980: E/AndroidRuntime(15375):    ... 11 more
  </code></pre>
  
  <p>The error with close:</p>
  
  <pre><code>02-20 11:57:47.880: E/AndroidRuntime(15853): FATAL EXCEPTION: main
  02-20 11:57:47.880: E/AndroidRuntime(15853): java.lang.RuntimeException: Unable to start activity ComponentInfo{de.vertretungsplan2/de.vertretungsplan2.Main}: java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase: /data/data/de.vertretungsplan2/databases/settings
  02-20 11:57:47.880: E/AndroidRuntime(15853):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2339)
  02-20 11:57:47.880: E/AndroidRuntime(15853):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2389)
  02-20 11:57:47.880: E/AndroidRuntime(15853):    at android.app.ActivityThread.access$600(ActivityThread.java:153)
  02-20 11:57:47.880: E/AndroidRuntime(15853):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1269)
  02-20 11:57:47.880: E/AndroidRuntime(15853):    at android.os.Handler.dispatchMessage(Handler.java:99)
  02-20 11:57:47.880: E/AndroidRuntime(15853):    at android.os.Looper.loop(Looper.java:137)
  02-20 11:57:47.880: E/AndroidRuntime(15853):    at android.app.ActivityThread.main(ActivityThread.java:5289)
  02-20 11:57:47.880: E/AndroidRuntime(15853):    at java.lang.reflect.Method.invokeNative(Native Method)
  02-20 11:57:47.880: E/AndroidRuntime(15853):    at java.lang.reflect.Method.invoke(Method.java:525)
  02-20 11:57:47.880: E/AndroidRuntime(15853):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:739)
  02-20 11:57:47.880: E/AndroidRuntime(15853):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:555)
  02-20 11:57:47.880: E/AndroidRuntime(15853):    at dalvik.system.NativeStart.main(Native Method)
  02-20 11:57:47.880: E/AndroidRuntime(15853): Caused by: java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase: /data/data/de.vertretungsplan2/databases/settings
  02-20 11:57:47.880: E/AndroidRuntime(15853):    at android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:55)
  02-20 11:57:47.880: E/AndroidRuntime(15853):    at android.database.sqlite.SQLiteDatabase.endTransaction(SQLiteDatabase.java:520)
  02-20 11:57:47.880: E/AndroidRuntime(15853):    at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:263)
  02-20 11:57:47.880: E/AndroidRuntime(15853):    at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:164)
  02-20 11:57:47.880: E/AndroidRuntime(15853):    at de.vertretungsplan2.Main.onCreate(Main.java:42)
  02-20 11:57:47.880: E/AndroidRuntime(15853):    at android.app.Activity.performCreate(Activity.java:5133)
  02-20 11:57:47.880: E/AndroidRuntime(15853):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
  02-20 11:57:47.880: E/AndroidRuntime(15853):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2293)
  02-20 11:57:47.880: E/AndroidRuntime(15853):    ... 11 more
  </code></pre>
  
  <p>This is my DBHandler:</p>
  
  <pre><code>package de.vertretungsplan2.helper;
  import android.content.ContentValues;
  import android.content.Context;
  import android.database.Cursor;
  import android.database.sqlite.SQLiteDatabase;
  import android.database.sqlite.SQLiteException;
  import android.database.sqlite.SQLiteOpenHelper;
  import android.util.Log;
  
  public class DBHandler extends SQLiteOpenHelper {
  
      private static final String TAG = "DBHandler";
      //Attributes of Database
      private static final int DATABASE_VERSION = 1;
      private static final String DATABASE_NAME = "settings";
  
      //Attributes of table "PASSWORD"
      private static final String TABLE_NAME_PW = "password";
      private static final String PASSWORD_ID ="id";
      private static final String PASSWORD_NAME = "password";
  
      //Attributes of table "KURS"
      private static final String TABLE_NAME_KURS = "kurs";
      private static final String KURS_ID = "id";
      private static final String KURS_NAME ="kurs";
  
      //Operations
      private static final String DROP_PW_TABLE = "DROP TABLE IF EXISTS " + TABLE_NAME_PW;
      private static final String DROP_KURS_TABLE = "DROP TABLE IF EXISTS " + TABLE_NAME_KURS;
  
      //Attributes of DBHandler 
  
      public DBHandler(Context context){
          super(context, DATABASE_NAME, null, DATABASE_VERSION);  
      }
  
      @Override
      public void onCreate(SQLiteDatabase db) {
          Log.i(TAG,"db aktion start, DBHandler-onCreate");
         /*
          if(db == null || !db.isOpen()) {
              db = getWritableDatabase();
          }*/
          createTables(db);
          insertPW("-1");
          insertKurs("-1");
          db.close();
          Log.i(TAG,"db aktion stop, DBHandler-onCreate");
      }
  
      private void createTables(SQLiteDatabase db){
          Log.i(TAG,"db aktion start, DBHandler-createTables");
          String CREATE_PW_TABLE = "CREATE TABLE IF NOT EXISTS  " + TABLE_NAME_PW +" (" + PASSWORD_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + PASSWORD_NAME + " TEXT);"; 
          String CREATE_KURS_TABLE = "CREATE TABLE IF NOT EXISTS " + TABLE_NAME_KURS +" (" + KURS_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + KURS_NAME + " TEXT);";
          if(db == null || !db.isOpen()) {
              db = getWritableDatabase();
          }
          db.execSQL(CREATE_PW_TABLE);
          Log.i(TAG,"db aktion start, nach PW Table erzeugen");
          db.execSQL(CREATE_KURS_TABLE);
          Log.i(TAG,"db aktion start, nach Kurs Table erzeugen");
          db.close();
          Log.i(TAG,"db aktion stop, DBHandler-createTables");
      }
  
  
      @Override
      public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
          Log.i(TAG,"db aktion start, DBHandler-onUpgrade");
          Log.w(TAG,"Upgrade der Datenbank von Version " + oldVersion 
                  + " zu " + newVersion + "; alle Daten werden gelöscht");
          db.execSQL(DROP_PW_TABLE);
          Log.i(TAG,"db aktion start, OnUpgrade nach Drop PW Table");
          db.execSQL(DROP_KURS_TABLE);
          Log.i(TAG,"db aktion start, OnUpgrade nach Drop kurs Table");
          db.close();
          Log.i(TAG,"db aktion start, OnUpgrade nach close db");
          onCreate(db);
          Log.i(TAG,"db aktion stop, DBHandler-onUpgrade");
      }
  
      public void insertPW(String PW){
          Log.i(TAG,"db aktion start, DBHandler-insertPW");
          long rowId = -1;
          try{
              SQLiteDatabase db = null;
              if(db == null || !db.isOpen()) {
                  db = getWritableDatabase();
              }
              ContentValues values = new ContentValues();
              values.put(PASSWORD_NAME, PW);
              rowId = db.insert(TABLE_NAME_PW, null, values);
              db.close();
          }catch (SQLiteException e){
              Log.e(TAG,"insert()",e);
          }finally{
              Log.d(TAG, "insert(): rowId=" + rowId);
              Log.i(TAG,"db aktion stop, DBHandler-insertPW");
          }
      }
  
      public void insertKurs(String Kurs){
          Log.i(TAG,"db aktion start, DBHandler-insertKurs");
          long rowId = -1;
          try{
              SQLiteDatabase db = null;
              if(db == null || !db.isOpen()) {
                  db = getWritableDatabase();
              }
              ContentValues values = new ContentValues();
              values.put(KURS_NAME, Kurs);
              rowId = db.insert(TABLE_NAME_KURS, null, values);
              db.close();
          }catch (SQLiteException e){
              Log.e(TAG,"insert()",e);
          }finally{
              Log.d(TAG, "insert(): rowId=" + rowId);
              Log.i(TAG,"db aktion stop, DBHandler-insertKurs");
          }
      }
  
      public String getPW(){
          Log.i(TAG,"db aktion start, DBHandler-getPW");
          SQLiteDatabase db = null;
          if(db == null || !db.isOpen()) {
              db = getReadableDatabase();
          }
          Cursor cursor = db.query(TABLE_NAME_PW, new String[] {PASSWORD_ID, PASSWORD_NAME},null,null,null,null,null);
          for(int i=0; i&lt;cursor.getCount();i++){
              cursor.moveToNext();
          }
          Log.i(TAG,"db aktion stop, DBHandler-getPW");
          db.close();
          return cursor.getString(1);
      }
  
      public String getKurs(){
          Log.i(TAG,"db aktion start, DBHandler-getKurs");
          SQLiteDatabase db = null;
          if(db == null || !db.isOpen()) {
              db = getReadableDatabase();
          }
          Cursor cursor = db.query(TABLE_NAME_KURS, new String[] {KURS_ID, KURS_NAME},null,null,null,null, null);
          for(int i=0; i&lt;cursor.getCount();i++){
              cursor.moveToNext();
          }
          db.close();
          Log.i(TAG,"db aktion stop, DBHandler-getKurs");
          return cursor.getString(1);
      }
  
      public int getPWCount(){
          Log.i(TAG,"db aktion start, DBHandler-getPWCount");
          String query = "SELECT * FROM " + TABLE_NAME_PW;
          SQLiteDatabase db = null;
          if(db == null || !db.isOpen()) {
              db = getReadableDatabase();
          }
          Cursor cursor = db.rawQuery(query,null);
          Log.i(TAG,"db aktion stop, DBHandler-getPWCount");
          db.close();
          return cursor.getCount();
      }
  
      public int getKursCount(){
          Log.i(TAG,"db aktion start, DBHandler-getKursCount");
          String query = "SELECT * FROM " + TABLE_NAME_KURS;
          SQLiteDatabase db = null;
          if(db == null || !db.isOpen()) {
              db = getReadableDatabase();
          }
          Cursor cursor = db.rawQuery(query,null);
          Log.i(TAG,"db aktion stop, DBHandler-getKursCount");
          db.close();
          return cursor.getCount();
      }
  }
  </code></pre>
  
  <p>I used this Logs to find out where the error apears but it does not help me.</p>
  
  <p>Thank you for help. </p>