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

打开相机按返回键出现ResultInfo结果传递失败异常求助

解决相机返回键触发的Kotlin非空参数异常问题

这个坑我之前踩过!当你在相机界面按返回键时,系统会返回result=0(也就是RESULT_CANCELED),而且返回的data是null,但你的代码里大概率把处理返回结果的参数声明成了非空类型,Kotlin的空校验机制直接就抛出异常了。咱们一步步解决:

先明确异常根源

你看到的java.lang.IllegalArgumentException: Parameter specified as non-null is null,就是Kotlin的Intrinsics.checkNotNull方法在检查时发现,你声明为非空的参数(比如Intent)实际传入了null,直接触发了崩溃。


解决方案分两种场景

场景1:使用传统的onActivityResult方法

如果你的代码还是用旧的onActivityResult处理相机返回,之前的错误写法可能是这样的:

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
    super.onActivityResult(requestCode, resultCode, data)
    if (requestCode == 1888) {
        // 尝试处理相机返回结果
    }
}

这里的data被声明为非空的Intent,但返回取消时data是null,直接触发异常。改成可空类型+空判断即可:

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    if (requestCode == 1888) {
        if (resultCode == Activity.RESULT_OK) {
            // 只有结果成功时才处理data,此时data大概率非空
            data?.let { intent ->
                // 你的业务逻辑:比如获取图片Uri
                val imageUri = intent.data
                // ...
            }
        } else {
            // 处理用户取消拍照的情况,比如提示或重置状态
            Toast.makeText(this, "你取消了拍照", Toast.LENGTH_SHORT).show()
        }
    }
}

场景2:使用Jetpack Activity Result API(推荐)

现在官方推荐用registerForActivityResult来处理返回结果,如果你之前的回调里把参数声明成了非空,比如:

// 错误示例:PickVisualMedia的回调参数声明为非空Uri
val pickImageLauncher = registerForActivityResult(ActivityResultContracts.PickVisualMedia()) { uri: Uri ->
    // 用户取消时uri为null,直接崩溃
}

或者用StartActivityForResult时直接断言data非空:

// 错误示例:用!!断言非空,取消时会炸
val cameraLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
    if (result.resultCode == Activity.RESULT_OK) {
        val data = result.data!!
        // ...
    }
}

正确的写法是把参数改成可空类型,并且做空判断:

// 示例1:PickVisualMedia的正确处理
val pickImageLauncher = registerForActivityResult(ActivityResultContracts.PickVisualMedia()) { uri: Uri? ->
    uri?.let {
        // 处理选中的图片Uri
    } ?: run {
        // 用户取消了操作,做对应处理
        Toast.makeText(this, "取消选择图片", Toast.LENGTH_SHORT).show()
    }
}

// 示例2:StartActivityForResult的正确处理
val cameraLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
    if (result.resultCode == Activity.RESULT_OK) {
        result.data?.let { intent ->
            // 处理相机返回的data
        }
    } else {
        // 处理取消逻辑
    }
}

核心总结

Kotlin的非空校验是编译+运行时双重检查,只要你声明了非空参数,就必须保证它不会为null。在处理系统返回的结果时,一定要考虑到用户取消操作的场景(此时data大概率为null),把对应的参数改成可空类型(加?),并在使用前做空安全处理(比如let、?:或者if (data != null))。

内容的提问来源于stack exchange,提问作者unpitted.com

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:00:21