Home > Net >  isOpen function valid for Room database or SQLite?
isOpen function valid for Room database or SQLite?

Time:10-07

Package androidx.room has this function where it should return if I'm connected to the database or not. But I want to make sure that this is the correct function for Room only and NOT SQLite, All I'm getting is false.

/**
 * 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();
}

CodePudding user response:

Yes it is, BUT you may well be mis-understanding when the database is opened, as you are getting false.

That is building the RoomDatabase does not (unless you force the matter) open the database. It leaves the actual open until it is required. It is only required when an attempt is actually made to access the database.

Consider the following that shows the status :-

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();
        }
    }
}

The @Database (TheDatabase) class includes a callback that writes to the log when onOpen or onCreate is called.

When run then the log includes the following :-

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$1 a.a.so69466269roomisopen.TheDatabase$1@112c3ea Opencounter = 0
2021-10-07 06:40:49.075 D/THEDATABSEINFO: onOpen has been called. For a.a.so69466269roomisopen.TheDatabase$1 a.a.so69466269roomisopen.TheDatabase$1@112c3ea OPenCounter = 0
2021-10-07 06:40:49.080 D/MAININFO: After Query true

So after the query (i.e. after the database has actually been accessed) isOpen returns true. Prior to the database being accessed isOpen returns false.

  • The first attempt (prior to getting the instance) issue a NPE (as would be expected) and therefore the message is not written to the log.

Force an Open

Now consider the @Database class TheDatabase which now has, since running the above, had the following line added (before the instance is returned).

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

Here's the TheDatabase class in full (modified for the force) :-

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);
        }
    };
}

Now when run the log includes :-

2021-10-07 07:07:16.264 D/THEDATABSEINFO: onOpen has been called. For a.a.so69466269roomisopen.TheDatabase$1 a.a.so69466269roomisopen.TheDatabase$1@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

i.e. the isOpen returns true as soon as the instance is obtained.

  • Related