[Android开发]SQLiteDatabase是否需要调用close()方法探究

简单整理一下android开发中的关于SQLiteDatabase的使用看法

 

1、在Android开发中,一般通过继承于抽象类SQLiteOpenHelper并重写构造函数来实现数据库的创建和更新操作。

 

public class AccountSQLiteHelper extends SQLiteOpenHelper {

 

    static String DB_NAME = "acc.db";

    static int DB_VERSION = 1; 

    static String TABLE_NAME = "acc";

 

    public AccountSQLiteHelper(Context context) {

        this(context, DB_NAMEnullDB_VERSION);

    }

 

    private AccountSQLiteHelper(Context context, String name, CursorFactory factory, intversion) {

        super(context, name, factory, version);

    }

 

    @Override

    public void onCreate(SQLiteDatabase db) {

        createTable(db);

    }

 

    @Override

    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

        dropTable(db);

        createTable(db);

    }

}

 

 

2、SQLiteOpenHelper有一个SQLiteDatabase成员变量,如下:

 

    private SQLiteDatabase mDatabase;

这个 SQLiteDatabase十分重要,它负责所有与数据库相关的操作,包括:创建数据库、打开数据库、执行SQL语句、关闭数据库等

 

3、获取SQLiteDatabase的方法是,调用下面两个方法实现:

 

public SQLiteDatabase getReadableDatabase();

 public SQLiteDatabase getWritableDatabase();

 

4、SQLiteOpenHelper的子类被实例化的时候,并不会马上创建数据库,只有当用户调用上面两个方法的时候,系统才会去创建数据库。首次执行上述两个函数的时候,会回调SQLiteOpenHelperonCreate(),onUpgrade(), onOpen()三个函数。

 

5、getReadableDatabase()和getWritableDatabase()最后都是调用了以下方法来获取mDatabase对象的。

 

private SQLiteDatabase getDatabaseLocked(boolean writable)

 

1、首次调用的时候,会初始化数据库信息,创建数据库,并打开与数据库的连接……然后返回mDatabase

2、如果mDatabase已打开,但只能用于读操作并且参数writable==true,此时返回mDatabase

3、如果mDatabase已被用户关闭了,那么将根据参数来设计打开模式,重新打开数据库的连接,并返回mDatabase

 

6、是否需要调用close()方法?什么时候调用?

 

SQLiteDatabase db = getWritableDatabase();
db.execSQL("DROP TABLE " + TABLE_NAME);
db.close(); //这个操作要不要加?

 

由于SQLiteOpenHelper内部只缓存一个数据库的连接(即一个SQLiteDatabase 实例mDatabase),

所以,当SQLiteOpenHelper被多个线程调用的时候,就需要注意了。

譬如:

线程A通过getWritableDatabase()获取了一个SQLiteDatabase 用来进行删除记录操作,

线程B通过getReadableDatabase()获取了一个SQLiteDatabase 用来进行其它操作,操作已完成正在close()

当线程A还在进行删除记录操作的时候,线程B调用了SQLiteDatabase.close()方法断开了数据库连接,

那么将会导致线程A的删除操作出现异常

09-25 11:45:17.069: W/System.err(12689): java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase: /data/data/com.example.testa/databases/acc.db

 

以下是我做的一个Demo测试。

一个线程负责写入操作,另一个线程负责close()操作,结果写线程在中途出了异常。

[Android开发]SQLiteDatabase是否需要调用close()方法探究_第1张图片

所以,一般来说不要随便close(),我认为在在Activity执行onDestory的时候调用close()比较合理,或者整个App退出的时候再close()。

你可能感兴趣的:([Android开发]SQLiteDatabase是否需要调用close()方法探究)