https://kotlinlang.org logo
#announcements
Title
# announcements
w

w_bianrytree

10/09/2019, 9:27 AM
The main problem I meet.
Copy code
class MyView:View{
  private val myChildView:View = findViewById(R.id.my_view_id)
  init{
     View.inflate(R.layout.my_layout,this)
  }
}
There is a chance that myChildView is null because inflation is executed after findViewById.
l

Luca Nicoletti

10/09/2019, 9:28 AM
It shouldn’t be a chance, it should always behave like this
w

w_bianrytree

10/09/2019, 9:29 AM
Or I should say there is a chance that myChildView is not null.
d

diesieben07

10/09/2019, 9:29 AM
You're letting
this
escape in the init block. that is usually a bad idea.
I can't reproduce this behavior with a minimal example though:
Copy code
fun main() {
    Foo()
}

fun getString() = "hello"

fun doWithString(s: String, foo: Foo) {
    println(s)
    println(foo.x)
}

class Foo {

    val x: String = getString()

    init {
        doWithString(x, this)
    }

}
prints "hello" twice correctly
l

Luca Nicoletti

10/09/2019, 9:32 AM
@diesieben07 that’s the expected behaviour
d

diesieben07

10/09/2019, 9:32 AM
Yes, I know.
Like I said in the other thread: The code runs in the order it is written in the source code.
w

w_bianrytree

10/09/2019, 9:33 AM
I think it may because the complier reordering happens?
d

diesieben07

10/09/2019, 9:34 AM
The compiler does not reorder things... What order are you seeing?
Are you saying in your case
findViewById
runs after
inflate
?
l

Luca Nicoletti

10/09/2019, 9:34 AM
It actually can re-order things, in order to optimize them
d

diesieben07

10/09/2019, 9:35 AM
Yes, but only if that doesn't change the observed behavior
w

w_bianrytree

10/09/2019, 9:36 AM
In my case that can happens imo. View inflation is just parsing an xml file. it doesn’t know it will change the findViewById result or not.
d

diesieben07

10/09/2019, 9:39 AM
what do you mean "can happen"... compilation either does one or the other ordering
its not ambiguous
w

w_bianrytree

10/09/2019, 9:40 AM
🤔 because I have 2 build on the same phone with the same code. 1 crashes and the other now. That makes me confuse.
d

diesieben07

10/09/2019, 9:43 AM
I am not too familiar with android, but can you decompile to java and check if the output is similar?
What crash d you see?
a

Alexander Johansson

10/09/2019, 9:43 AM
Isn’t this less of a case of order of execution, and more of a case of which functions you are using? There can be a case where the View is not actually inflated in the heirarchy, so findViewById will not find the referenced View.
l

Luca Nicoletti

10/09/2019, 9:44 AM
From the code above there should be always a crash
findViewById
execute before inflating the view will return
null
d

diesieben07

10/09/2019, 9:45 AM
The view ids are different, Luca
But I am really out of my water here with Android. So I'll 🤐
l

Luca Nicoletti

10/09/2019, 9:45 AM
The
ids
are different because one is referencing a layout
Which contain a view with the
id
findViewById
is trying to find
if the
layout
is not inflated,
findViewById
will return
null
So, that code should always throw a
NPE
w

w_bianrytree

10/09/2019, 9:48 AM
But in my case. The crash is not always happening. Interesting enough. I already ship the code in production and the un-crashed user is much higher than crashes. 😂
l

Luca Nicoletti

10/09/2019, 9:49 AM
Can you check the decompiled code?
a

Alexander Johansson

10/09/2019, 10:14 AM
You could just find your child view after the inflation has happened.
Copy code
private lateinit var myChildView: View

init {
    View.inflate(R.layout.my_layout,this)
    myChildView = findViewById(R.id.my_view_id)
}
Or even lazily using
by lazy {}
l

Luca Nicoletti

10/09/2019, 10:16 AM
@Alexander Johansson we're not searching for a solution 😂
w

wasyl

10/09/2019, 10:40 AM
There’s also an example in the docs (https://kotlinlang.org/docs/reference/classes.html): “During an instance initialization, the initializer blocks are executed in the same order as they appear in the class body, interleaved with the property initializers” So it shouldn’t be possible for your code to not crash 😕
Unless the base class does something that makes the
findViewById
not crash
l

Luca Nicoletti

10/09/2019, 10:45 AM
Yep, that post confirmed what we were saying :)
Thanks for sharing though :)
w

wasyl

10/09/2019, 10:46 AM
Yep I just wanted to provide some sources. I expect OP’s snippet doesn’t show entire picture. For one it’s impossible to inflate a view into another View, so the base class must be
ViewGroup
for example
👍 1
4 Views