Android SQLite 打开数据库时出错

Android SQLite error opening database

我使用的是 SQLiteOpenHelper,我的 class 工作得很好,但是我的一个方法确实有错误,我在从游标获取 getCount() 后没有关闭数据库.现在,每次启动应用程序时,我都会收到错误消息:

    java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase:

我正在尝试关闭该连接,但我无法对 class 执行任何方法,因为我总是收到此错误。

我实际上重新创建了一个全新的 Android 应用程序并将我的源文件一个一个地复制过来,但我仍然收到相同的错误。

在我的MainActivity.java:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    BillDatabaseHelper db = new BillDatabaseHelper(this);
    db.recreateDatabases(); // this is the line that causes the error

    viewPagerFragment = new ViewPagerFragment();
    transaction = manager.beginTransaction();
    transaction.add(R.id.placeholderMain, viewPagerFragment);
    transaction.commit();
}

在我的DatabaseHelper.java:

public void recreateDatabases() {
    SQLiteDatabase db = this.getWritableDatabase();
    onCreate(db);
}

@Override
public void onCreate(SQLiteDatabase db) {
    db.execSQL("DROP TABLE IF EXISTS " + TABLE_TRANSACTIONS);
    db.execSQL("DROP TABLE IF EXISTS " + TABLE_BILL_INFO);
    db.execSQL("DROP TABLE IF EXISTS " + TABLE_REMINDERS);
    db.execSQL("DROP TABLE IF EXISTS " + TABLE_BILL_DATE_INFO);
    db.execSQL("DROP TABLE IF EXISTS " + TABLE_PAYDATES);

    String strCreateTransactionsTableSQL =
            "CREATE TABLE " + TABLE_TRANSACTIONS + "("
            + KEY_TRAN_ID + " INTEGER PRIMARY KEY,"
            + KEY_TRAN_DESC + " TEXT,"
            + KEY_TRAN_AMOUNT + " REAL,"
            + KEY_TRAN_PURCHASE_DATE + " TEXT);";

    String strCreateBillInfoTableSQL =
            "CREATE TABLE " + TABLE_BILL_INFO + "("
            + KEY_BILL_ID + " INTEGER PRIMARY KEY,"
            + KEY_BILL_NAME + " TEXT,"
            + KEY_BILL_BALANCE + " FLOAT,"
            + KEY_BILL_DUE_DATE + " TEXT,"
            + KEY_BILL_MINIMUM + " FLOAT,"
            + KEY_BILL_CURRENT + " FLOAT);";

    String strCreateRemindersTableSQL =
            "CREATE TABLE " + TABLE_REMINDERS + "("
            + KEY_REM_ID + " INTEGER PRIMARY KEY,"
            + KEY_REM_NAME + " TEXT,"
            + KEY_REM_DESC + " TEXT,"
            + KEY_REM_LOCATION + " TEXT,"
            + KEY_REM_START + " TEXT);";

    String strCreateBillDateTableSQL =
            "CREATE TABLE " + TABLE_BILL_DATE_INFO + "("
            + KEY_BILLDATE_PK + " INTEGER PRIMARY KEY,"
            + KEY_BILLDATE_TOBILL_ID + " INTEGER,"
            + KEY_BILLDATE_BILLID + " INTEGER,"
            + KEY_BILLDATE_PAYDATE + " TEXT,"
            + KEY_BILLDATE_BILLDATE + " TEXT,"
            + KEY_BILLDATE_OWEDTODAY + " CHARACTER(1),"
            + KEY_BILLDATE_BALANCE + " FLOAT,"
            + KEY_BILLDATE_CURRENT + " FLOAT,"
            + "FOREIGN KEY(" + KEY_BILLDATE_PK + ") REFERENCES " + TABLE_BILL_INFO + "(" + KEY_BILL_ID + "));";

    String strCreatePaydatesSQL =
            "CREATE TABLE " + TABLE_PAYDATES + "("
            + KEY_PAYDATE_ID + " INTEGER PRIMARY KEY,"
            + KEY_PAYDATE_DATE + " TEXT);";

    db.execSQL(strCreateTransactionsTableSQL);
    db.execSQL(strCreateBillInfoTableSQL);
    db.execSQL(strCreateRemindersTableSQL);
    db.execSQL(strCreateBillDateTableSQL);
    db.execSQL(strCreatePaydatesSQL);
}

我应该在哪里关闭这个连接?任何帮助将不胜感激。

您不必关闭数据库连接,请参阅:

Best place to close database connection

您可以像这样打开数据库:

public class YourDatabase extends SQLiteOpenHelper {

    public static final int DATABASE_VERSION = 1;
    public static final String DATABASE_NAME = "yourdatabase.db";
    private SQLiteDatabase database;

    public YourDatabase(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    // call this function once
    public void open() throws SQLException {
        database = this.getWritableDatabase();
    }

    private void create(SQLiteDatabase database) {
        database.execSQL("CREATE TABLE contacts (TEXT `name`, TEXT `number`)");
    }

    @Override
    public void onCreate(SQLiteDatabase database) {
        create(database);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // TODO Auto-generated method stub
    }
}

只需要调用一次open(),然后就可以使用database属性来写入或读取数据库,像这样database.rawQuery(selectQuery, null);