【问题标题】:Can't get SQLite writable database无法获取 SQLite 可写数据库
【发布时间】:2013-06-13 21:14:16
【问题描述】:

我正在尝试实现 android SQLite 使用设计模式,以确保每个应用程序打开一个 SQLiteDatabase 实例。

public class BaseDataSource {

    private static final CustomSQLiteHelper dbHelper = CustomSQLiteHelper.getInstance();

    protected static SQLiteDatabase database;

    static {
        //HERE RISES EXCEPTION
        BaseDataSource.database = BaseDataSource.dbHelper.getWritableDatabase();
    }



    private void close() {      
        if(null != BaseDataSource.database && BaseDataSource.database.isOpen()) {
            BaseDataSource.database.close();

            if(null != BaseDataSource.dbHelper) {
                BaseDataSource.dbHelper.close();                
            }
        }
    }

    protected BaseDataSource() {}


    protected void finalize () throws Throwable {
        close();
        super.finalize();       
    }
} 

但是当我的应用程序启动时,我得到了这种异常:

Caused by: java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase: /data/data/com.xxx/databases/xxx.db

在创建类之前如何打开和关闭 SQLiteDatabse 数据库?

更新

我发现了自己的错误。它在 CustomSQLiteHelper 类中。在onCreate 方法中,我关闭了数据库。我尝试了在互联网上找到的所有解决方案,因此我犯了一个错误。

【问题讨论】:

标签: android android-sqlite


【解决方案1】:

如果您要进行任何事情,则首先需要以写入数据库的形式打开。所以为此使用这种方法 并像这样调用

openAsWrite();

    public void openAsWrite() throws SQLException {
            db = DBHelper.getWritableDatabase();
        }

        // ---closes the database---
        public void close() throws SQLException {
            DBHelper.close();
        }

【讨论】:

    【解决方案2】:

    获取数据库对象时使用以下模式:

    try {
        if (sDatabase != null) {
            if (!sDatabase.isOpen()) {
                sDatabase = sContext.openOrCreateDatabase(DATABASE_NAME, 0, null);
            }
        } else {
            // open database here
            sDatabase = sContext.openOrCreateDatabase(DATABASE_NAME, 0, null);
        }
        Log.d(TAG, "Database successfully opened.");
    } catch (SQLException e) {
        Log.e(TAG, "" + e);
    }
    

    【讨论】:

    • 这将确保如果数据库对象为空或数据库已关闭然后只请求获取数据库对象
    • openOrCreateDatabase函数对SQLiteHelper有什么影响,因为我实现了CustomSQLiteHelper,因为支持数据库创建和升级?
    【解决方案3】:

    将数据库对象用作静态对象会使您的类表现得像这样。

    • 在加载类时创建数据库实例。
    • 在调用 finalize 方法时关闭数据库连接。
    • 您的类将不再获取数据库连接,并且将拥有已关闭的数据库实例。
    • 最终当尝试访问已关闭的实例时,它会向您弹出错误

    我认为你应该使用不同的方法会更好。

    【讨论】:

    • 但是在静态块中出现异常,这意味着在类负载上(100% 是第一次尝试创建数据库对象)。非常合乎逻辑的答案,我同意实施非常糟糕。我会尝试重新思考。 :)
    猜你喜欢
    • 2019-10-13
    • 2020-08-03
    • 2018-05-28
    • 2012-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多