2014-02-20 25 views
3

我的數據庫出了問題。 當應用程序啓動時,它應該創建帶有表格的數據庫(如果它們不存在),但應用程序在啓動後立即崩潰。當我打開logcat後關閉數據庫告訴我「我想打開一個已經關閉的對象」,當我不關閉數據庫時,我得到了錯誤「getReadableDatabase called recursively」。我不知道該怎麼辦。有時它可以工作,但是當我卸載應用程序並再次安裝錯誤時,它會出錯。遞歸調用的Android sqlite getdatabase

沒有關閉錯誤:

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 

誤差接近:

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 

這是我DBHandler:

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

我用這個日誌,找出了錯誤apears,但它不能幫助我。

謝謝你的幫助。

+0

你可以看到我的答案在這個鏈接:http://stackoverflow.com/a/30554384/2114308 – Phuong

回答

18

當數據庫文件不存在時調用getWritableDatabase()會導致打開幫助程序onCreate()被調用。

db作爲參數傳遞給onCreate()是打開的數據庫。您應該使用它來進行初始化,而不是像在insertPW()和其他方法中那樣調用getWritableDatabase()。由於您剛剛將本地db變量初始化爲null,因此db == null || !db.isOpen()條件無效。

+0

啊沒關係。再次感謝您的幫助:D – user3328547