Android Studio为选项菜单项加事件遇MenuItem空安全错误求助
这个错误是Kotlin的空安全机制在提醒你:参数item是可空类型MenuItem?,直接访问它的itemId属性存在空指针风险,所以编译器禁止这种不安全的调用。下面给你几种实用的解决办法:
方案一:使用?.let安全调用+when表达式(推荐)
利用Kotlin的let函数在item非空时执行逻辑,同时用when代替繁琐的if-else,代码更简洁易读:
override fun onOptionsItemSelected(item: MenuItem?): Boolean { item?.let { menuItem -> when(menuItem.itemId) { R.id.home -> { val homeIntent = Intent(this, SignIn::class.java) startActivity(homeIntent) } R.id.sign_in -> { val signInIntent = Intent(this, SignIn::class.java) startActivity(signInIntent) } R.id.close -> { System.exit(0) } } } return super.onOptionsItemSelected(item) }
item?.let会自动判断item是否为null:如果是null,lambda内的代码不会执行;如果非null,menuItem会被自动转为非空类型MenuItem,可以安全访问itemId。
方案二:非空断言!!(不推荐,谨慎使用)
如果你能100%确定这个回调里的item永远不会为null,可以用!!强制断言非空:
override fun onOptionsItemSelected(item: MenuItem?): Boolean { when(item!!.itemId) { R.id.home -> { val homeIntent = Intent(this, SignIn::class.java) startActivity(homeIntent) } R.id.sign_in -> { val signInIntent = Intent(this, SignIn::class.java) startActivity(signInIntent) } R.id.close -> { System.exit(0) } } return super.onOptionsItemSelected(item) }
⚠️ 注意:如果item实际为null,!!会直接抛出NullPointerException,所以这种方式只适合你能绝对保证item非空的场景。
方案三:显式判空后处理
先检查item是否为null,为空则直接返回父类实现,非空再处理逻辑:
override fun onOptionsItemSelected(item: MenuItem?): Boolean { if (item == null) { return super.onOptionsItemSelected(item) } when(item.itemId) { R.id.home -> { val homeIntent = Intent(this, SignIn::class.java) startActivity(homeIntent) } R.id.sign_in -> { val signInIntent = Intent(this, SignIn::class.java) startActivity(signInIntent) } R.id.close -> { System.exit(0) } } return super.onOptionsItemSelected(item) }
这种方式逻辑清晰,适合习惯传统判空写法的开发者。
另外,你可以优化重复的Intent代码,比如提取一个通用的启动Activity方法,让代码更简洁:
private fun launchActivity(clazz: Class<*>) { startActivity(Intent(this, clazz)) }
然后在when里直接调用:R.id.home -> launchActivity(SignIn::class.java)
内容的提问来源于stack exchange,提问作者Ben Ghaleb
相关产品推荐
相关产品推荐

