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

API 33下使用ActivityResultContracts.CaptureVideo()触发DeadObjectException崩溃

问题

使用ActivityResultContracts.CaptureVideo()实现视频拍摄功能时,仅在API 33设备上出现DeadObjectException崩溃,API 32、30、28等低版本运行完全正常。

崩溃堆栈信息

2022-09-19 20:32:02.047 577-601/system_process W/WindowManager: Exception thrown during dispatchAppVisibility Window{5b4304c u0
com.my.package/com.my.package.activities.MainActivity
EXITING}
android.os.DeadObjectException
at android.os.BinderProxy.transactNative(Native Method)
at android.os.BinderProxy.transact(BinderProxy.java:584)
at android.view.IWindow$Stub$Proxy.dispatchAppVisibility(IWindow.java:536)
at com.android.server.wm.WindowState.sendAppVisibilityToClients(WindowState.java:3489)
at com.android.server.wm.WindowContainer.sendAppVisibilityToClients(WindowContainer.java:1199)
at com.android.server.wm.WindowToken.setClientVisible(WindowToken.java:398)
at com.android.server.wm.ActivityRecord.setClientVisible(ActivityRecord.java:6564)
at com.android.server.wm.ActivityRecord.postApplyAnimation(ActivityRecord.java:5280)
at com.android.server.wm.ActivityRecord.commitVisibility(ActivityRecord.java:5235)
at com.android.server.wm.ActivityRecord.commitVisibility(ActivityRecord.java:5239)
at com.android.server.wm.AppTransitionController.handleClosingApps(AppTransitionController.java:1098)
at com.android.server.wm.AppTransitionController.handleAppTransitionReady(AppTransitionController.java:286)
at com.android.server.wm.RootWindowContainer.checkAppTransitionReady(RootWindowContainer.java:975)
at com.android.server.wm.RootWindowContainer.performSurfacePlacementNoTrace(RootWindowContainer.java:842)
at com.android.server.wm.RootWindowContainer.performSurfacePlacement(RootWindowContainer.java:784)
at com.android.server.wm.WindowSurfacePlacer.performSurfacePlacementLoop(WindowSurfacePlacer.java:177)
at com.android.server.wm.WindowSurfacePlacer.performSurfacePlacement(WindowSurfacePlacer.java:126)
at com.android.server.wm.WindowSurfacePlacer.performSurfacePlacement(WindowSurfacePlacer.java:115)
at com.android.server.wm.WindowSurfacePlacer$Traverser.run(WindowSurfacePlacer.java:57)
at android.os.Handler.handleCallback(Handler.java:942)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.os.HandlerThread.run(HandlerThread.java:67)
at com.android.server.ServiceThread.run(ServiceThread.java:44)

实现代码

private fun takeVideo() {
    val media = File.createTempFile("temp_file", ".mp4", this.requireContext().cacheDir)
    val fileUri = FileProvider.getUriForFile(this.requireContext(), "${requireContext().packageName}.provider", media)
    this.fileUri = Uri.parse(media.absolutePath)
    this.takeVideoResult.launch(fileUri)
}

/**
 * A function to handle registering an activity result for video capture
 */
private val takeVideoResult = registerForActivityResult(ActivityResultContracts.CaptureVideo()) { success ->
    if (success) {
        this.fileUri?.let { uri ->
            this.attachmentUris.add(uri)
            this.updateAttachmentViews()
        }
    }
}

分析与解决方案

1. 首要修复:Uri使用逻辑错误

你的代码存在明显的Uri误用问题:传给相机的是FileProvider生成的content格式Uri,但后续保存的却是通过文件绝对路径解析的file格式Uri。API 33对文件权限管控更严格,这种不一致的Uri处理会触发系统窗口管理的异常,这是崩溃的主要诱因。

修复方式:直接保存FileProvider生成的content Uri,不要重新解析文件路径:

private fun takeVideo() {
    val media = File.createTempFile("temp_file", ".mp4", this.requireContext().cacheDir)
    val fileUri = FileProvider.getUriForFile(this.requireContext(), "${requireContext().packageName}.provider", media)
    this.fileUri = fileUri // 直接保留content格式的Uri
    this.takeVideoResult.launch(fileUri)
}

2. API 33系统层面的补充优化

虽然上述修复能解决大部分情况,但API 33初期版本确实存在窗口管理相关的DeadObjectException小概率问题,可补充以下优化:

  • 确保registerForActivityResult在Fragment/Activity的onCreate阶段注册,避免动态注册导致的生命周期不一致。
  • 捕获异常做兜底处理:
private val takeVideoResult = registerForActivityResult(ActivityResultContracts.CaptureVideo()) { success ->
    try {
        if (success) {
            this.fileUri?.let { uri ->
                this.attachmentUris.add(uri)
                this.updateAttachmentViews()
            }
        }
    } catch (e: DeadObjectException) {
        Toast.makeText(requireContext(), "拍摄失败,请重试", Toast.LENGTH_SHORT).show()
    }
}

3. 权限检查确认

API 33仍需确保已申请并获得Manifest.permission.CAMERA权限,避免因权限缺失引发连锁异常。

内容的提问来源于stack exchange,提问作者Dwebtron

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 22:55:23