Android SQLite DB何时关闭

w.d*_*hue 93 sqlite android

我在android上使用SQLite数据库.我的数据库管理器是一个单例,现在正在初始化时打开与数据库的连接.将数据库保持打开状态是安全的,这样当有人调用我的类来处理数据库时,它已经打开了吗?或者我应该在每次访问之前和之后打开和关闭数据库.只是让它一直打开是否有任何伤害?

谢谢!

jam*_*mes 60

我会一直打开它,并在一些生命周期方法中关闭它,如onStoponDestroy.这样,您可以在每次使用之前通过调用isDbLockedByCurrentThreadisDbLockedByOtherThreads单个SQLiteDatabase对象轻松检查数据库是否已被使用.这将阻止对数据库的多次操作,并使您的应用程序免于潜在的崩溃

所以在你的单身人士中,你可能有一个像这样的方法来获得你的单个SQLiteOpenHelper对象:

private SQLiteDatabase db;
private MyDBOpenHelper mySingletonHelperField;
public MyDBOpenHelper getDbHelper() {
    db = mySingletonHelperField.getDatabase();//returns the already created database object in my MyDBOpenHelper class(which extends `SQLiteOpenHelper`)
    while(db.isDbLockedByCurrentThread() || db.isDbLockedByOtherThreads()) {
        //db is locked, keep looping
    }
    return mySingletonHelperField;
}
Run Code Online (Sandbox Code Playgroud)

所以无论何时你想使用你的开放助手对象,都要调用这个getter方法(确保它是有线程的)

您的单例中的另一种方法可能是(在您尝试调用上面的getter之前每隔一段时间调用一次):

public void setDbHelper(MyDBOpenHelper mySingletonHelperField) {
    if(null == this.mySingletonHelperField) {
        this.mySingletonHelperField = mySingletonHelperField;
        this.mySingletonHelperField.setDb(this.mySingletonHelperField.getWritableDatabase());//creates and sets the database object in the MyDBOpenHelper class
    }
}
Run Code Online (Sandbox Code Playgroud)

您可能还想关闭单例中的数据库:

public void finalize() throws Throwable {
    if(null != mySingletonHelperField)
        mySingletonHelperField.close();
    if(null != db)
        db.close();
    super.finalize();
}
Run Code Online (Sandbox Code Playgroud)

如果您的应用程序的用户能够非常快速地创建许多数据库交互,您应该使用我上面演示的内容.但如果有最小的数据库交互,我不会担心它,只是每次都创建和关闭数据库.

  • WARD isDbLockedByOtherThreads()是Depricated并且自API 16返回false.同时检查isDbLockedByCurrentThread()将给出无限循环,因为它停止当前线程并且没有任何东西可以"解锁DB"以使该方法返回true. (3认同)
  • 旋转是一种非常糟糕的技术.请参阅下面的答案. (2认同)

mix*_*xel 20

截至目前,没有必要检查数据库是否被另一个线程锁定.当您在每个线程中使用单例SQLiteOpenHelper时,您是安全的.来自isDbLockedByCurrentThread文档:

此方法的名称来自与数据库建立活动连接的时间,这意味着该线程正在对数据库进行实际锁定.如今,不再存在真正的"数据库锁定",尽管如果线程无法获取数据库连接以执行特定操作,则可能会阻塞.

isDbLockedByOtherThreads 自API级别16以来已弃用.


mat*_*kin 13

关于问题:

我的数据库管理器是一个单例,现在正在初始化时打开与数据库的连接.

我们应该划分'开放数据库','打开连接'.SQLiteOpenHelper.getWritableDatabase()给出了一个打开的数据库.但是我们不必像在内部那样控制连接.

将数据库保持打开状态是安全的,这样当有人调用我的类来处理数据库时,它已经打开了吗?

是的.如果正确关闭了事务,则连接不会挂起.请注意,如果GC最终确定,您的数据库也将自动关闭.

或者我应该在每次访问之前和之后打开和关闭数据库.

关闭SQLiteDatabase实例除了关闭连接之外没有任何重要意义,但如果此时有一些连接,那么这是一个开发人员的错误.此外,在SQLiteDatabase.close()之后,SQLiteOpenHelper.getWritableDatabase()将返回一个新实例.

只是让它一直打开是否有任何伤害?

不,没有.另请注意,在不相关的时刻关闭数据库,例如在Activity.onStop()中关闭数据库可能会关闭活动连接并使数据保持不一致状态.