Can anytime AppDatabase in Android Room be null?

2019-03-04 18:38发布

问题:

While adding Room Database, it is suggested to use Singleton Design Pattern

Note: You should follow the singleton design pattern when instantiating an AppDatabase object, as each RoomDatabase instance is fairly expensive, and you rarely need access to multiple instances.

So, adding Room Database, following Google example which is written in Java, in will be as below

private var INSTANCE: AppDatabase? = null

fun getInstance(context: Context): AppDatabase? {
    if (INSTANCE == null){
        synchronized(AppDatabase::class){
            INSTANCE = Room.databaseBuilder(context.applicationContext,
                    AppDatabase::class.java, "app_database")
                    .build()
        }
    }
    return INSTANCE
}

When I call getInstance, compiler suggests that getInstance can be null. So my question is there any case that getInstance be null and do I have to check if it's null. If not, then how should I instantiate AppDatabase so that getInstance return AppDatabase not AppDatabase? and it fits documentation recommendation?

回答1:

Use something like this to make sure it is not null

object DatabaseSource {
    private lateinit var INSTANCE: AppDatabase

    fun getInstance(context: Context): AppDatabase {
        if (!::INSTANCE.isInitialized) {
            synchronized(AppDatabase::class) {
                if (!::INSTANCE.isInitialized) {
                    INSTANCE = Room.databaseBuilder(context.applicationContext,
                                                    AppDatabase::class.java,
                                                    "app_database").build()
                }
            }
        }
        return INSTANCE
    }
}

Call it with:

val db = DatabaseSource.getInstance(context)

And this will never be null so you no longer have that issue.

I added double locking to be safer for thread safety on the getInstance() call.

But really you should be using dependency injection with singletons to avoid this passed in dependency of context and this manual creation/locking. You'll have to have the context available everywhere which is a bad pattern.

This also acts as an answer to your other post which is apparently a duplicate of this one.