为什么我会收到 UninitializedPropertyAccessException?安卓科特林

问题描述

所以我试图通过另一个有意图的活动从在编辑文本中输入的文本发送文本数据。我正在尝试将文本数据从 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.access$3600(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)

我很困惑我在这里做错了什么。这是我的家庭活动代码。我已经在 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 类的第 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)
    ...
}