Android计算器应用出现NullPointerException问题求助
问题根源
你的NullPointerException是因为类成员变量在Activity的onCreate方法执行前就调用了findViewById。此时布局还没通过setContentView加载到Activity中,所有视图查找都会返回null,后续给这些null对象设置点击监听器时就会触发空指针异常。
修复方案
核心是确保findViewById在setContentView之后执行,以下是两种常用的修复方式:
方式1:使用lateinit var延迟初始化变量
将所有视图变量声明为lateinit var,告诉Kotlin这些变量会在后续完成初始化,然后在onCreate中完成赋值:
package com.example.calculadora import android.support.v7.app.AppCompatActivity import android.os.Bundle import android.text.Editable import android.widget.Button import android.widget.EditText class MainActivity : AppCompatActivity() { // 用lateinit var声明变量,延迟初始化 private lateinit var button0: Button private lateinit var button1: Button private lateinit var button2: Button private lateinit var button3: Button private lateinit var button4: Button private lateinit var button5: Button private lateinit var button6: Button private lateinit var button7: Button private lateinit var button8: Button private lateinit var button9: Button private lateinit var button_equal: Button private lateinit var button_par_ab: Button private lateinit var button_par_cl: Button private lateinit var button_coma: Button private lateinit var buttonAC: Button private lateinit var button_mul: Button private lateinit var button_div: Button private lateinit var button_sum: Button private lateinit var button_dif: Button private lateinit var caja: EditText override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // 在setContentView之后初始化所有视图变量 initViews() detectarEntrada() } private fun initViews() { button0 = findViewById(R.id.button0) button1 = findViewById(R.id.button1) button2 = findViewById(R.id.button2) button3 = findViewById(R.id.button3) button4 = findViewById(R.id.button4) button5 = findViewById(R.id.button5) button6 = findViewById(R.id.button6) button7 = findViewById(R.id.button7) button8 = findViewById(R.id.button8) button9 = findViewById(R.id.button9) button_equal = findViewById(R.id.button_equal) button_par_ab = findViewById(R.id.button_par_ab) button_par_cl = findViewById(R.id.button_par_cl) button_coma = findViewById(R.id.button_coma) buttonAC = findViewById(R.id.buttonAC) button_mul = findViewById(R.id.button_por) button_div = findViewById(R.id.button_div) button_sum = findViewById(R.id.button_sum) button_dif = findViewById(R.id.button_dif) caja = findViewById(R.id.caja_de_texto) } fun imprimir(simbolo: String) { val texto = caja.text.toString() val texto_a_poner = texto + simbolo caja.text = Editable.Factory.getInstance().newEditable(texto_a_poner) } fun detectarEntrada() { button0.setOnClickListener { imprimir("0") } button1.setOnClickListener { imprimir("1") } button2.setOnClickListener { imprimir("2") } button3.setOnClickListener { imprimir("3") } button4.setOnClickListener { imprimir("4") } button5.setOnClickListener { imprimir("5") } button6.setOnClickListener { imprimir("6") } button7.setOnClickListener { imprimir("7") } button8.setOnClickListener { imprimir("8") } button9.setOnClickListener { imprimir("9") } button_par_ab.setOnClickListener { imprimir("(") } button_par_cl.setOnClickListener { imprimir(")") } button_coma.setOnClickListener { imprimir(",") } button_mul.setOnClickListener { imprimir("*") } button_div.setOnClickListener { imprimir("/") } button_sum.setOnClickListener { imprimir("+") } button_dif.setOnClickListener { imprimir("-") } buttonAC.setOnClickListener { caja.text = Editable.Factory.getInstance().newEditable("0") } } }
方式2:直接在onCreate中声明并初始化变量
如果不想用lateinit,也可以把所有视图变量的声明和初始化都放在onCreate内部,再传递给detectarEntrada方法:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val button0 = findViewById<Button>(R.id.button0) val button1 = findViewById<Button>(R.id.button1) // ... 其他视图变量同理 val caja = findViewById<EditText>(R.id.caja_de_texto) detectarEntrada(button0, button1, ..., caja) } fun detectarEntrada(button0: Button, button1: Button, ..., caja: EditText) { // 在这里设置监听器 }
额外建议
作为Android新手,推荐你使用View Binding替代findViewById,它能自动生成视图绑定类,避免手动查找视图时的错误,使用起来更简洁安全。启用View Binding后,你可以直接通过绑定类访问所有视图,无需再写findViewById。
内容的提问来源于stack exchange,提问作者mrt
相关产品推荐
相关产品推荐

