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

targetSdk35下getSerializableExtra废弃及Activity跳转空指针崩溃修复

修复Intent传递Serializable时的NullPointerException崩溃

核心崩溃原因

从崩溃日志和代码来看,空指针触发在ActivityOtpAuthentication的init方法第80行,大概率是以下几种情况:

  1. loginRespModalModal.getUser()返回null,但代码用!!强制非空直接触发崩溃;
  2. getSerializableExtraProvider扩展方法实现错误,导致获取的LoginRespModal为null,后续调用方法时触发空指针;
  3. 嵌套的User类未实现Serializable接口,导致整个对象序列化失败,传递后获取到null。

分步修复方案

1. 确保序列化逻辑正确

  • 检查并修改User类,让它也实现Serializable接口:
    class User : Serializable {
        // 原有字段与方法
    }
    
    若内部类未实现序列化,会导致整个LoginRespModal对象无法正常传递,最终获取到null。
  • 验证getSerializableExtraProvider扩展方法的正确性,适配Android 13+的标准实现如下:
    import android.content.Intent
    import android.os.Build
    import java.io.Serializable
    
    inline fun <reified T : Serializable> Intent.getSerializableExtraProvider(key: String): T? {
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            getSerializableExtra(key, T::class.java)
        } else {
            @Suppress("DEPRECATION")
            getSerializableExtra(key) as? T
        }
    }
    

2. 消除强制非空的风险

移除代码中的!!操作符,改用安全调用和空值降级逻辑,避免直接崩溃:

private fun init() {
    // ...其他Extra获取逻辑
    intent.getSerializableExtraProvider<LoginRespModal>(Keys.userInfo)?.let { loginResp ->
        loginRespModalModal = loginResp
        // 安全处理User对象
        loginResp.user?.let { user ->
            otp = user.getOtp() ?: "" // 根据业务需求设置默认值
            id = user.getId()?.toString() ?: ""
        } ?: run {
            // User为null时的降级处理
            Toast.makeText(this, "用户信息异常,请重新登录", Toast.LENGTH_SHORT).show()
            finish()
        }
    } ?: run {
        // 未获取到LoginRespModal时的处理
        Toast.makeText(this, "登录信息丢失,请重新操作", Toast.LENGTH_SHORT).show()
        finish()
    }
    // ...其他逻辑
}

3. 确保传递的Extra不为null

在ActivityLogin跳转前,先校验loginRespModal是否为空,避免传递无效值:

val intent = Intent(this@ActivityLogin, ActivityOtpAuthentication::class.java)
loginRespModal?.let {
    intent.putExtra(Keys.userInfo, it)
} ?: run {
    Toast.makeText(this, "登录失败,请重试", Toast.LENGTH_SHORT).show()
    return
}
intent.putExtra(Keys.isFrom, Keys.login)
intent.putExtra(Keys.otpData, binding.edInput.text.toString())
startActivity(intent)

长期优化建议

  • 改用Parcelable替代Serializable:Android平台上Parcelable的序列化效率更高,且能避免Serializable的隐性问题,可通过Android Studio的「Parcelable Code Generator」插件自动生成实现代码;
  • 使用类型安全的传递方式:比如采用Jetpack的Activity Result API配合自定义Contract,或用ViewModel共享数据,减少对Intent Extra的直接依赖。

内容的提问来源于stack exchange,提问作者Anish M.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 14:39:51