为什么会出现 UninitializedPropertyAccessException? Android 科特林

Why do I get an UninitializedPropertyAccessException? Android Kotlin

所以我试图通过另一个 activity 有意地从编辑文本中输入的文本发送文本数据。我正在尝试将文本数据从 HomeActivity 发送到 SearchResultActivity。但是,当我单击调用 startActivity(intent) 的按钮时,我的应用程序被强行关闭并且出现此异常:

2021-04-27 02:46:30.622 13861-13861/com.dicoding.movieapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.dicoding.movieapp, PID: 13861
kotlin.UninitializedPropertyAccessException: lateinit property activityHomeBinding has not been initialized
    at com.dicoding.movieapp.home.HomeActivity.onClick(HomeActivity.kt:39)
    at android.view.View.performClick(View.java:7500)
    at android.view.View.performClickInternal(View.java:7472)
    at android.view.View.access00(View.java:824)
    at android.view.View$PerformClick.run(View.java:28657)
    at android.os.Handler.handleCallback(Handler.java:938)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:239)
    at android.app.ActivityThread.main(ActivityThread.java:8107)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:626)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1015)

我很困惑我在这里做错了什么。这是我的家庭密码 activity。我已经在 onCreate 函数中初始化了绑定,但为什么它仍然说它未初始化?

 override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    val activityHomeBinding = ActivityHomeBinding.inflate(layoutInflater)
    setContentView(activityHomeBinding.root)
    activityHomeBinding.btnSearch.setOnClickListener(this)
}

    override fun onClick(v: View?) {
    when (v?.id){
        R.id.btn_search -> {
            val searchText = activityHomeBinding.editTextSearch.text.toString().trim()
            if (searchText == null){
                activityHomeBinding.editTextSearch.error = "Field cannot be empty"
            } else {
                val intent = Intent(this@HomeActivity, SearchResultActivity::class.java)
                intent.putExtra(SearchResultActivity.EXTRA_SEARCH,searchText)
                startActivity(intent)
            }
        }
    }

这是我的代码 SearchResultActivity:

private lateinit var searchResultActivity: ActivitySearchResultBinding

companion object {
    const val EXTRA_SEARCH = "extra_search"
}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    searchResultActivity = ActivitySearchResultBinding.inflate(layoutInflater)
    setContentView(searchResultActivity.root)

    searchResultActivity.testIntent.text = intent.getStringExtra(EXTRA_SEARCH)
}

错误消息指出,在您的 HomeActivity class 的第 39 行,您指向的是未初始化的 属性。这是因为您定义了 2 个 activityHomeBinding 具有不同的作用域

class HomeActivity : AppCompatActivity(), View.OnClickListener {
    
    ...

    lateinit var activityHomeBinding: ActivityHomeBinding <-- 1st one, globally scoped

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val activityHomeBinding = ActivityHomeBinding.inflate(layoutInflater) <-- 2nd one, function-scoped (to onCreate)
        setContentView(activityHomeBinding.root)
        activityHomeBinding.btnSearch.setOnClickListener(this)
    }

    override fun onClick(v: View?) {
        when (v?.id){
            R.id.btn_search -> {
                val searchText = activityHomeBinding.editTextSearch.text.toString().trim() <-- this points at 1st one, (i.e. globally scoped)
                if (searchText == null){
                    activityHomeBinding.editTextSearch.error = "Field cannot be empty"
                } 

                ...
            }
        }
    }
}

解决方案是简单地从您要膨胀绑定的行中删除 val。这样,您无需创建新变量,而是将膨胀的绑定分配给全局范围的 lateinit var activityHomeBinding,然后您的 onClick 回调可以使用它。

所以从

override fun onCreate(savedInstanceState: Bundle?) {
    ...
    val activityHomeBinding = ActivityHomeBinding.inflate(layoutInflater)
    ...
}

override fun onCreate(savedInstanceState: Bundle?) {
    ...
    activityHomeBinding = ActivityHomeBinding.inflate(layoutInflater)
    ...
}