isOpen 函数对 Room 数据库或 SQLite 有效吗?

isOpen function valid for Room database or SQLite?

Package androidx.room 具有此功能,它应该 return 无论我是否连接到数据库。但我想确保这仅适用于 Room 并且 NOT SQLite,我得到的都是错误的。

/**
 * Returns true if database connection is open and initialized.
 *
 * @return true if the database connection is open, false otherwise.
 */
public boolean isOpen() {
    // We need to special case for the auto closing database because mDatabase is the
    // underlying database and not the wrapped database.
    if (mAutoCloser != null) {
        return mAutoCloser.isActive();
    }

    final SupportSQLiteDatabase db = mDatabase;
    return db != null && db.isOpen();
}

是的,但是当数据库打开时你可能会误解,因为你得到的是错误的。

那是建立RoomDatabase 不会(除非你强迫此事)打开数据库。它让实际打开直到需要它。只有在实际尝试访问数据库时才需要它。

考虑以下显示状态的内容:-

public class MainActivity extends AppCompatActivity {

    TheDatabase db;
    AllDao dao;
    List<Table1> table1List;
    private static final String TAG = "MAININFO";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        try {
            Log.d(TAG, "Getting Room instance" + db.isOpen());
        } catch (Exception e) {
            e.printStackTrace();
        }
        db = TheDatabase.getInstance(this);
        try {
            Log.d(TAG,"Getting DAO" + db.isOpen());
        } catch (Exception e) {
            e.printStackTrace();
        }
        dao = db.getAllDao();
        try {
            Log.d(TAG, "Querying Table1 " + db.isOpen());
        } catch (Exception e) {
            e.printStackTrace();
        }
        table1List = dao.getAll();
        try {
            Log.d(TAG, "After Query " + db.isOpen());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

@Database (TheDatabase) class 包含一个在调用 onOpen 或 onCreate 时写入日志的回调。

当 运行 时,日志包括以下内容:-

2021-10-07 06:40:49.037 D/MAININFO: Getting DAOfalse
2021-10-07 06:40:49.039 D/MAININFO: Querying Table1 false
2021-10-07 06:40:49.069 D/THEDATABSEINFO: onCreate has been called. For a.a.so69466269roomisopen.TheDatabase a.a.so69466269roomisopen.TheDatabase@112c3ea Opencounter = 0
2021-10-07 06:40:49.075 D/THEDATABSEINFO: onOpen has been called. For a.a.so69466269roomisopen.TheDatabase a.a.so69466269roomisopen.TheDatabase@112c3ea OPenCounter = 0
2021-10-07 06:40:49.080 D/MAININFO: After Query true

所以查询后(即实际访问数据库后)isOpenreturns真。在访问数据库之前 isOpen returns false.

  • 第一次尝试(在获取实例之前)发出 NPE(如预期的那样),因此消息未写入日志。

强制打开

现在考虑 @Database class TheDatabase,自从上面 运行 之后,添加了以下行(在实例之前返回)。

instance.getOpenHelper().getWritableDatabase(); //<<<<< FORCE OPEN

这里是 TheDatabase class 的完整内容(针对强制进行了修改):-

abstract class TheDatabase extends RoomDatabase {
    abstract AllDao getAllDao();
    private static final String DATABASE_NAME = "thedatabase.db";
    private static final String TAG = "THEDATABSEINFO";

    private static volatile TheDatabase instance = null;
    private static int counter = 0;

    static TheDatabase getInstance(Context context) {
        if (instance == null) {
            instance = Room.databaseBuilder(
                    context,
                    TheDatabase.class,
                    DATABASE_NAME
            )
                    .addCallback(callback)
                    .allowMainThreadQueries()
                    .build();
        }
        instance.getOpenHelper().getWritableDatabase(); //<<<<< FORCE OPEN
        return instance;
    }

    static Callback callback = new RoomDatabase.Callback() {
        @Override
        public void onCreate(@NonNull SupportSQLiteDatabase db) {
            super.onCreate(db);
            Log.d(TAG,"onCreate has been called. For " + this.getClass().getName() + " " + this + " Opencounter = " + counter);
        }

        @Override
        public void onOpen(@NonNull SupportSQLiteDatabase db) {
            super.onOpen(db);
            Log.d(TAG,"onOpen has been called. For " + this.getClass().getName() + " " + this + " OPenCounter = " + counter++);
        }

        @Override
        public void onDestructiveMigration(@NonNull SupportSQLiteDatabase db) {
            super.onDestructiveMigration(db);
        }
    };
}

现在 运行 日志包括:-

2021-10-07 07:07:16.264 D/THEDATABSEINFO: onOpen has been called. For a.a.so69466269roomisopen.TheDatabase a.a.so69466269roomisopen.TheDatabase@112c3ea OPenCounter = 0
2021-10-07 07:07:16.264 D/MAININFO: Getting DAOtrue
2021-10-07 07:07:16.266 D/MAININFO: Querying Table1 true
2021-10-07 07:07:16.271 D/MAININFO: After Query true

isOpen returns 一旦获得实例就为真。