Android启动SecondActivity报错:空对象引用调用虚拟方法
问题现象
启动应用跳转SecondActivity时直接崩溃,抛出异常:Unable to start activity ComponentInfo Attempt to invoke virtual method on a null object reference
已完成的自查:
- 应用共包含2个Activity,SecondActivity布局内放置了1个TextView、1个Button
- 已对上述两个控件编写了
findViewById初始化逻辑 - 已排查所有控件ID,不存在重名情况,仍触发空指针报错
问题根因
本次空指针和ID重名没有关系,是两处基础逻辑错误导致的:
- 缺失
setContentView()布局加载步骤
Activity在onCreate生命周期中,必须先调用setContentView()绑定对应的布局文件,将布局实例加载到当前页面的视图树后,findViewById()才能遍历视图树匹配到对应ID的控件。你的SecondActivity代码在super.onCreate()执行完成后,直接调用findViewById(),完全没有加载自身布局的步骤,因此findViewById<TextView>(R.id.textView3)返回的result对象为null,执行result.text = getString(R.string.resDisplay)这行代码时就会直接触发空指针,页面启动瞬间就会崩溃,根本不会走到后续按钮绑定的逻辑。 - 跨Activity非法操作非当前页面的控件
即使补上setContentView()代码,按钮点击事件中操作的b1~b9系列控件属于MainActivity的布局内容,既没有在SecondActivity中做初始化,也不存在于SecondActivity的视图树中,这些变量在SecondActivity的上下文里全为null,点击重玩按钮时同样会触发空指针异常。
修复方案
按以下步骤修改代码即可解决问题:
- 在
super.onCreate(savedInstanceState)代码之后立刻添加布局绑定代码,加载SecondActivity对应的布局文件(将布局名替换为你项目中SecondActivity实际对应的xml文件名):
setContentView(R.layout.activity_second)
- 删除SecondActivity按钮点击事件中所有操作
b1~b9控件的代码:这些控件属于MainActivity,不能在SecondActivity中直接跨页面修改。跨页面直接操作其他Activity的控件本身就是违反Android组件生命周期逻辑的写法,正确的做法是回到MainActivity后,在MainActivity自身的生命周期方法里重置棋盘状态。 - 调整跳转MainActivity的Intent参数,避免返回栈堆积旧的Activity实例,修正后SecondActivity的核心代码如下:
class SecondActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 必须先加载布局 setContentView(R.layout.activity_second) val result = findViewById<TextView>(R.id.textView3) result.text = getString(R.string.resDisplay) val replay = findViewById<Button>(R.id.button3) replay.setOnClickListener { val intent = Intent(this, MainActivity::class.java) // 清除栈中已有的MainActivity实例,避免返回键逻辑异常 intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP startActivity(intent) finish() } } }
- 在MainActivity中重写
onResume()生命周期方法,在方法内完成棋盘控件的重置,这样每次从SecondActivity回到MainActivity时,都会自动执行重置逻辑:
override fun onResume() { super.onResume() // 重置所有棋盘按钮状态 b1.text = "" b2.text = "" b3.text = "" b4.text = "" b5.text = "" b6.text = "" b7.text = "" b8.text = "" b9.text = "" listOf(b1, b2, b3, b4, b5, b6, b7, b8, b9).forEach { it.isEnabled = true } }
你贴出的SecondActivity布局文件本身不存在语法或ID配置问题,不需要修改。
内容的提问来源于stack exchange,提问作者Divyansh Singh
相关产品推荐
相关产品推荐

