You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

第二次点击录制按钮时应用崩溃问题求助(附代码片段)

解决第二次点击录制按钮应用崩溃的问题

嘿,我一眼就看出问题所在了——你每次调用record()方法时都直接重新初始化MediaRecorder,但第一次录制后没有正确释放资源,导致第二次调用时Recorder还处于占用状态,自然就崩溃了。咱们来一步步修复:

核心问题分析

MediaRecorder有严格的状态生命周期:初始化→配置→准备→录制→停止→释放。你的代码每次点击都会重复执行recorder.setAudioSource()这类配置操作,但第一次录制后没走完stop()+release()的收尾流程,第二次直接操作就会触发状态异常,进而导致应用崩溃。

修复方案

  1. 添加状态变量跟踪录制状态,比如private var isRecording = false
  2. record()方法里分情况处理:正在录制就停止释放资源;未录制才初始化启动
  3. 用安全的异常处理保证资源在任何场景下都能被释放

修改后的完整代码示例

private var isRecording = false
private lateinit var recorder: MediaRecorder
private var tempFile: File? = null

private fun record() {
    if (isRecording) {
        // 停止录制并释放资源
        try {
            recorder.stop()
        } catch (e: IllegalStateException) {
            Log.d("recording error", "Recorder wasn't recording properly:", e)
        } finally {
            recorder.release()
            isRecording = false
        }
        return
    }

    // 初始化录制流程
    recorder = MediaRecorder()
    try {
        val path: File = filesDir
        tempFile = File.createTempFile("audioTemp", ".3gp", path)

        recorder.apply {
            setAudioSource(MediaRecorder.AudioSource.MIC)
            setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP)
            setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB)
            setOutputFile(tempFile?.absolutePath)
            prepare()
            start()
            isRecording = true
        }
    } catch (e: IOException) {
        Log.d("recording error", "Failed to create temp file or prepare recorder:", e)
        // 出错时也要及时释放资源
        if (::recorder.isInitialized) {
            recorder.release()
        }
    } catch (e: IllegalStateException) {
        Log.d("recording error", "Recorder state error:", e)
        if (::recorder.isInitialized) {
            recorder.release()
        }
    }
}

额外注意点

  • 记得在Activity/Fragment的onDestroy()方法里也做检查,如果还在录制状态,一定要强制释放资源,避免内存泄漏
  • 提前申请好录音权限(RECORD_AUDIO),如果是Android 10及以上版本,存储到App私有目录不需要额外的存储权限

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

火山引擎 最新活动