什么时候应该关闭SQLiteDatabase对象? [英] When should I close an SQLiteDatabase object?

查看:90
本文介绍了什么时候应该关闭SQLiteDatabase对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我几个小时都不断收到这个令人讨厌的运行时错误,这使我的应用程序崩溃了:

I kept getting this annoying runtime error for hours, which crashed my app:

java.lang.RuntimeException:执行时发生错误doInBackground().

java.lang.RuntimeException: An error occured while executing doInBackground().

由以下原因引起:java.lang.IllegalStateException:尝试重新打开一个已经关闭的对象:SQLiteDatabase

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

经过一些调试后,我发现发生这种情况是因为我在 onDestory()方法中关闭了SQLiteDatabse对象.当我同时调用 SQLiteOpenHelper.close()时,就会发生这种情况.

After some debugging I found that it happens because I close my SQLiteDatabse object, in the onDestory() method. It happens when I call SQLiteOpenHelper.close() as well.

@Override
protected void onDestroy() {
    super.onDestroy();
    _cursor.close(); //is fine
    _db.close(); //causes error
    _databaseHelper.close(); //causes error too (probably calls db.close() internally..?)
    SharedFunctions.d("closed!"); //ignore this ugly thing
}

这提出了两个问题

  1. 我做对了吗?(可能不是)
  2. 如果不在 onDestroy 方法中,我何时 需要关闭SQLiteDatabase对象?
  1. Am I doing it right? (probably not)
  2. When do I need to close a SQLiteDatabase object, if not in the onDestroy method?

DB和Helper类是静态的:

The DB and the Helper classes are static:

public class MainActivity extends Activity {

    private Cursor _cursor = null;
    private MyCursorAdapter _myCursorAdapter = null;
    private ListView _listView = null;

    private static SalaryDatabaseHelper _databaseHelper = null;
    public static SQLiteDatabase db = null;

    ...

我在onCreate()方法中初始化_databaseHelper:

I initialize _databaseHelper in the onCreate() method:

//get database helper
        if(_databaseHelper == null)
            _databaseHelper = SalaryDatabaseHelper.getInstance(this);

db AsyncTask.doInBackground()中初始化:

protected Boolean doInBackground(Integer... data)
{
    try {
        //get writable database
        if(db == null)
            db = SalaryDatabaseHelper.getDbInstance();

我对帮助器类和数据库类使用单例:(均通过帮助器类访问)

I use singletons for the helper class and the database class: (both accessed via the helper class)

class MyDatabaseHelper extends SQLiteOpenHelper{

    private static SalaryDatabaseHelper _instance = null;
    private static SQLiteDatabase _dbInstance = null;

    //singletons
    public static synchronized SalaryDatabaseHelper getInstance(Context context)
    {
        // Use the application context, which will ensure that you
        // don't accidentally leak an Activity's context.
        if (_instance == null)
            _instance = new SalaryDatabaseHelper(context.getApplicationContext());

        return _instance;
    }

    public static synchronized SQLiteDatabase getDbInstance() {
        if(_dbInstance == null)
            _dbInstance = _instance.getWritableDatabase();

        return _dbInstance;
    }

    ...

推荐答案

您的 SQLiteOpenHelper instance static ,因此在范围上是全局的.考虑到这一点:

Your SQLiteOpenHelper instance is static, and therefore global in scope. With that in mind:

我做对了吗?(可能不是)

Am I doing it right? (probably not)

否.

如果不在onDestroy方法中,何时需要关闭SQLiteDatabase对象?

When do I need to close a SQLiteDatabase object, if not in the onDestroy method?

从不.SQLite是事务性的.关闭数据库没有任何风险.

Never. SQLite is transactional. There is no risk from failing to close the database.

是的,这也让我感到不快,但是我经历了七个阶段的悲伤,并且我继续接受"

在更简单的方案中,只有一个具有数据库访问权限的组件,您可以在销毁该组件时将其关闭.在您的情况下,您的整个应用程序(包括后台线程)都可以访问数据库.在这种情况下,您永远不会关闭它.

In simpler scenarios, where there is a single component with access to the database, you might close it when that component is destroyed. In your case, your whole app, including background threads, have access to the database. In that case, you simply never close it.

这篇关于什么时候应该关闭SQLiteDatabase对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆