Hi. I'm following a codelabs course from google "A...
# announcements
j
Hi. I'm following a codelabs course from google "Android Room with a View - Kotlin" and I don't understand the part which the database is instancied with a volatile var into an companion object. Why the
INSTANCE
var is assigned to a
tempInstance
to check if it is null ? and why in the synchronizrd block the
INSTANCE
is assigned to
instance
and the
instance
is returned instead of
INSTANCE
? I missunderstood something i guess.
a
the temporary val is used for smart casting (https://kotlinlang.org/docs/reference/typecasts.html#smart-casts):
Copy code
val tempInstance = INSTANCE
if(tempInstance != null)
    return tempInstance //Kotlin automatically casts tempInstance to WordRoomDatabase, because its a val and cannot be changed
vs
Copy code
if(INSTANCE != null)
   return INSTANCE //INSTANCE is still a WordRoomDatabase?, because theoretically it could've been set to null between the null check and the return
And for your second question:
INSTANCE
and
instance
is the same at the end of the
synchronized
-block, so it doesn't matter which one is returned
j
Oh okay, thanks for the explanation
So if I want, I can do that if I don't whant to use temp var ?:
Copy code
if (INSTANCE != null) {
                return INSTANCE as AppDatabase
            }
for explicitly give the type
I modified that like this:
Copy code
fun getDatabase(context: Context): AppDatabase {
            return if (INSTANCE != null) {
                INSTANCE as AppDatabase
            } else {
                synchronized(this) {
                    Room.inMemoryDatabaseBuilder(
                        context.applicationContext,
                        AppDatabase::class.java
                    ).build()
                }
            }
        }
for a more idiomatic and functional way, do you thinks I'm right with that ?
a
This snippet doesn't store the generated instance, it will always produce a new instance
j
Because of the explicit cast ?
a
INSTANCE
is never assigned. you need something like
INSTANCE = Room.inMemoryDatabaseBuilder(...)
j
Ho right 😂
a
but yeah, I personally lean towards the more functional side and thus i use
if
,
when
more often as expressions rather than statements
j
But in my case it's not possible because I must assign INSTANCE to the created database, right ?
a
right, its not fully functional, but its as close as possible 😄 Even in Haskell you have to have some "imperative" code and some state, otherwise you can't do anything with it
j
Yeah okay, thanks for all explanations. I prefer my approach with explicit cast rather than a temp variable 🙂
a
just make sure that
getDatabase()
is not called from different threads, otherwise it can lead to hard to debug problems
👍 1
a
You could add a
.also { INSTANCE = it}
in your version @Jérôme Gully
😲 1
@Andreas Sinz if he makes sure that it's not called from different threads then why would he even need the synchronized? I guess it doesn't make a lot of sense to have the synchronized only around the assignment though?
a
@Alowaniak you are right, this
synchronized()
-block is actually useless, the whole body should be synchronized