Android:MediaRecorder stop()方法导致应用冻结问题排查
解决三星Galaxy S9录屏停止后应用冻结的问题
嘿,这个问题我之前在适配三星设备的时候也踩过坑!OnePlus这类设备对MediaRecorder的状态校验比较宽松,但三星的ROM在硬件资源管理上要严格得多,停止录制时的冻结大概率是UI线程阻塞或者资源释放顺序错误导致的,给你几个针对性的解决方案:
1. 务必在子线程中执行MediaRecorder的停止与释放操作
三星设备上mediaRecorder.stop()和release()操作涉及底层硬件资源回收,耗时比其他设备长,如果在UI线程执行,直接会导致应用冻结(本质是ANR)。把这部分逻辑移到子线程里:
private void stopRecordingSafely() { new Thread(() -> { // 先标记录制状态为停止,避免重复操作 isRecording = false; try { // 先销毁VirtualDisplay,再处理MediaRecorder if (mVirtualDisplay != null) { mVirtualDisplay.release(); mVirtualDisplay = null; } if (mediaRecorder != null) { mediaRecorder.stop(); mediaRecorder.reset(); mediaRecorder.release(); mediaRecorder = null; } // 最后释放MediaProjection if (mMediaProjection != null) { mMediaProjection.stop(); mMediaProjection = null; } } catch (IllegalStateException | RuntimeException e) { // 捕获三星设备可能抛出的状态异常,避免崩溃 e.printStackTrace(); // 兜底释放资源 if (mediaRecorder != null) { mediaRecorder.reset(); mediaRecorder.release(); mediaRecorder = null; } } }).start(); }
2. 严格遵循资源释放的顺序
录屏时的资源依赖链是:MediaProjection → VirtualDisplay → MediaRecorder的Surface,停止时必须反向释放:
- 先释放VirtualDisplay(切断Surface的来源)
- 再停止并释放MediaRecorder
- 最后释放MediaProjection
如果顺序搞反,MediaRecorder的Surface还被VirtualDisplay占用,三星设备会因为资源锁死导致冻结。
3. 增加状态校验,避免重复操作
给你的录制逻辑加个状态标记(比如boolean isRecording),只有在isRecording == true的时候才执行停止流程,防止重复调用stop()导致的异常:
// 开始录制前标记状态 private void startRecording() { if (!isRecording) { isRecording = true; // 初始化MediaRecorder、创建VirtualDisplay等逻辑 } } // 停止时先判断状态 private void stopRecording() { if (isRecording) { stopRecordingSafely(); } }
4. 适配三星设备的MediaRecorder异常
部分三星设备的MediaRecorder在停止时可能会抛出非标准的RuntimeException,一定要捕获这些异常并兜底释放资源,避免因为异常导致资源泄漏进而冻结应用。
按照这个流程调整后,应该就能解决三星S9上的冻结问题了,核心就是把耗时的硬件操作移出UI线程,严格管理资源释放顺序~
内容的提问来源于stack exchange,提问作者Kewitschka
相关产品推荐
相关产品推荐

