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

Kotlin安卓开发启动MainActivity出现AndroidRuntime致命异常是什么原因

错误原因

你的报错核心是Activity初始化阶段调用findViewById时上下文为空,具体问题点如下:

  • findViewById需要Activity加载完布局、上下文初始化完成后才能正常调用,你现在直接在类成员变量声明阶段就执行findViewById初始化控件,此时Activity还没完成attachBaseContext绑定上下文,也还没执行onCreate里的setContentView加载布局,调用findViewById自然会触发空指针异常。
  • 额外兼容问题:XML里声明的是FloatingActionButton类型的按钮,你代码里强转成了Button,虽然不会直接触发本次崩溃,但类型不匹配后续也可能引发类型转换异常。
修复方案

修改MainActivity.kt的控件声明逻辑,将控件初始化放到setContentView之后执行即可,参考修改后的代码:

package com.example.studycountdowntimer

import android.annotation.SuppressLint
import android.os.Bundle
import android.os.CountDownTimer
import android.view.View
import android.widget.EditText
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import com.google.android.material.floatingactionbutton.FloatingActionButton

class MainActivity : AppCompatActivity() {
    private var startMilliseconds = 60000L

    private lateinit var cdTimer: CountDownTimer
    private var onRun: Boolean = false
    var timeInMilliseconds = 0L

    // 先声明为lateinit,暂不初始化
    private lateinit var timeInput: EditText
    private lateinit var timeShow: TextView
    private lateinit var buttonStart: FloatingActionButton
    private lateinit var buttonPause: FloatingActionButton
    private lateinit var buttonStop: FloatingActionButton

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        // 加载完布局之后再初始化控件
        timeInput = findViewById(R.id.inputTime)
        timeShow = findViewById(R.id.showTime)
        buttonStart = findViewById(R.id.startButton)
        buttonPause = findViewById(R.id.pauseButton)
        buttonStop = findViewById(R.id.stopButton)

        buttonStart.setOnClickListener {
            if (onRun) {
                pauseTime()
                buttonPause.visibility = View.VISIBLE
            } else {
                val time  = timeInput.text.toString()
                timeInMilliseconds = time.toLong() *60000L
                startTime(timeInMilliseconds)
            }
        }

        buttonStop.setOnClickListener {
            stopTime()
        }
    }

    private fun pauseTime() {
        cdTimer.cancel()
        onRun = false
    }

    private fun startTime(timeInSeconds: Long) {
        cdTimer = object : CountDownTimer(timeInSeconds, 1000) {
            @SuppressLint("SetTextI18n")
            override fun onFinish() {
                timeShow.text = "You did it!"
            }

            override fun onTick(p0: Long) {
                timeInMilliseconds = p0
                updateTextUI()
            }
        }
        cdTimer.start()

        onRun = true
        buttonStart.visibility = View.INVISIBLE
    }

    private fun stopTime() {
        timeInMilliseconds = startMilliseconds
        updateTextUI()
    }

    @SuppressLint("SetTextI18n")
    private fun updateTextUI() {
        val minutes = (timeInMilliseconds / 1000) / 60
        val seconds = (timeInMilliseconds / 1000) % 60
        val hours = minutes / 60

        timeShow.text = "$hours:$minutes:$seconds"
    }
}

如果要更高效安全的处理控件绑定,也可以开启Kotlin视图绑定功能,避免手动写findViewById的冗余代码。

内容的提问来源于stack exchange,提问作者devAndre

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 03:18:03