https://kotlinlang.org logo
Title
j

JungIn Choi

04/07/2021, 1:07 AM
Day25
• Review Lesson6, revisiting the details ◦ synchronized block - only one thread of execution at a time can enter the block ◦ smart cast - (link) Compiler infers the variable’s type and internally casts it. It allows access to the nullable variable after checking it’s actually not null ◦ Testing & annotations @ Before , @ Test , @ After ◦ <_merge_> tag & reusing layout (link) ◦ requireNotNull - throws an exception if a value is null ◦ Creating ViewModel ▪︎ needs application, since ViewModel has to use resources(string/style ..) ▪︎ needs DAO, since ViewModel has to access the database through DAO interface ▪︎ needs Factory to instantiate the ViewModel - Reference to the “database” is not needed, since there is DAO interface passed. However, existence of database should be checked when the ViewModel is created. ▪︎ Inside the Fragment/onCreateView(), create instance of Factory, get reference to the ViewModel, set data binding for ViewModel • Conceptual basics about android thread, process, runnable (blog post) • Lesson7 ◦ RecyclerView, Adapter, ViewHolder ▪︎ ViewHolder - holds views, store information for RecyclerView, works as RecyclerView’s main interface ▪︎ Adapter methods - getItemCount, onBindViewHolder
Self-Comment
• Proceeding the lesson is important, but reviewing is also important. It’s a difficult mission to maintain the balance, since if I spend too much time and energy on reviewing, I can’t proceed. But if I just proceed with unsolved understandings, it’s quite useless. • Curious about android testing, testing methods, specific use cases, flexible and wise usage of various testings in actual industrial deployment. • Faced this bug
Test running failed: No test results. onError: commandError=true message=INSTRUMENTATION_FAILED:
while running the provided test code. Seemed to be just another build..gradle..version..kind of problem, so I skipped this at that moment, but I’ll have to resolve this now while reviewing..
Goals Tomorrow
• Finish reviewing lesson6, proceed more on lesson7
🔥 2
1. smart cast
@Volatile
private var INSTANCE: SleepDatabase? = null
fun getInstance(context: Context): SleepDatabase{
  synchronized(this){
    var instance = INSTANCE 
// code for null checking & creating database
    return instance
  }
}
In the lecture, the lecturer mentioned something about smart cast. But at that time, I did not know what smart cast is, and which part of this code is showing this smart cast feature. It did not seem to be the core part of this lesson (which is actually true), so I just passed away and proceed the lecture. So, I checked what smart cast is, and now I understand. INSTANCE which is declared as a nullable variable, but not null in actual usage, can be returned in getInstance function which returns a not-null SleepDatabase type variable.
b

Bryan L

04/07/2021, 1:11 AM
companion object {
        @Volatile
        private var INSTANCE: NoteDatabase? = null
        
        fun getDatabase(
            context: Context,
            scope: CoroutineScope,
        ) : NoteDatabase {
            return INSTANCE ?: synchronized(this) {
                val instance = Room.databaseBuilder(
                    context.applicationContext,
                    NoteDatabase::class.java,
                    "note_database"
                )
                 .addCallback(NoteDatabaseCallback(scope))
                 .build()
                INSTANCE = instance
                instance
            }
Here is a code sample from my Note database you can see for another example that includes the filler code( // code for null checking and creating database )
j

JungIn Choi

04/07/2021, 1:15 AM
Thanks bryan. That ?: elvis thing returns INSTANCE if it’s not null, and if it’s null, creates the instance from that synchronized block and returns it. Is my understanding correct?
b

Bryan L

04/07/2021, 1:22 AM
Correct. it's like say
val x: Int? = null
val number = x ?: 5
println(x)

output = 5
So it get's the value(If not null) on the left of
?:
else if left value is null than use this value instead. Helps control the flow of null values if they are a possibility. In this case. If an instance of the database already exists, return it. If not(it's null), create an instance of the database
If that makes any sense
j

JungIn Choi

04/07/2021, 1:29 AM
Thanks I got it.:blob-sunglasses: I was quite curious why kotlin always shouts out null checking etc. as it’s fascinating feature, but now I get it as the lecture talks about database.
:android-dance: 1
🔥 1
2. Re-using layouts The lecturer just mentioned “merge tag can be used to eliminate redundant layouts when including layouts”, but I had no idea about this. I didn’t know what “include” tag is, what this “redundant layouts” look like, and why it’s actually a problem, and how this “merge” tag solves it. So, I first looked at the official android document which the lecturer attached, but still did not get it. And then I found some guy in stackoverflow who had exactly the same question in my mind. Since I lacked understanding about <include> tag and layouts in firsthand, this long answer was helpful. <include> tag just seems like #include macro in C, nothing special as the answerer says. But when include file has multiple widget, there comes the problem of redundant layouts, which just deepen the view hierarchy. <merge> tag eliminates that redundant layout part. I remember that deep view hierarchy is a bad thing since we have to search for the view component at runtime. But I’m also curious if there’s any quantitative way to check my view hierarchy, any profiling methods that show the problems in my view hierarchy, worst case searching time etc.