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
相关产品推荐
相关产品推荐

