You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 08:23:19