“lateinit” or “by lazy” when defining global andro

2020-08-21 03:07发布

问题:

When defining a global android.widget variable, e.g. TextView, is it preferable to use lateinit or by lazy? I initially thought using by lazy would be preferred as its immutable but I'm not entirely sure.

by lazy example:

class MainActivity: AppCompatActivity() {

    val helloWorldTextView by lazy { findViewById(R.id.helloWorldTextView) as TextView }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        updateTextView(helloWorldTextView)
    }

    fun updateTextView(tv: TextView?) {
        tv?.setText("Hello?")
    }
}

lateinit example:

class MainActivity: AppCompatActivity() {

    lateinit var helloWorldTextView: TextView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        helloWorldTextView = findViewById(R.id.helloWorldTextView) as TextView
        updateTextView(helloWorldTextView)
    }

    fun updateTextView(tv: TextView?) {
        tv?.setText("Hello?")
    }
}

Are there any benefits of using one over the other when defining a global android.widget var/val? Are there any pitfalls with using by lazy to define a android.widget val? Is the decision just based on whether you want a mutable or immutable value?

回答1:

There's one pitfall with by lazy. The widget property would be read-only and therefore technically final (in Java terms). But there's no documented guarantee that onCreate() is called only once for an instance. Also findViewById() could return null.

So using lateinit is preferable and you'll get an exception to tell you if the val was used before onCreate().

A third possibility would be Android synthetic properties. Then you don't need to worry about the variables at all.

import kotlinx.android.synthetic.main.activity_main.*

helloWorldTextView.text = "Hello?"