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

三星设备上android.media.AudioRecord.read崩溃问题排查与解决咨询

三星设备AudioRecord崩溃原因分析与解决办法

据Google Play反馈,以下崩溃仅出现在三星设备上:

[libc.so] abort
SIGABRT

backtrace:
  #00  pc 0x00000000000537d4  /apex/com.android.runtime/lib64/bionic/libc.so (abort+168)
  #01  pc 0x00000000006f365c  /apex/com.android.art/lib64/libart.so (art::Runtime::Abort(char const*)+596)
  #02  pc 0x0000000000016ea8  /apex/com.android.art/lib64/libbase.so (android::base::SetAborter(std::__1::function<void (char const*)>&&)::$_3::__invoke(char const*)+80)
  #03  pc 0x0000000000006f60  /system/lib64/liblog.so (__android_log_assert+312)
  #04  pc 0x00000000000b20bc  /system/lib64/libaudioclient.so (android::ClientProxy::releaseBuffer(android::Proxy::Buffer*)+240)
  #05  pc 0x00000000000654c0  /system/lib64/libaudioclient.so (android::AudioRecord::releaseBuffer(android::AudioRecord::Buffer const*)+168)
  #06  pc 0x0000000000068484  /system/lib64/libaudioclient.so (android::AudioRecord::read(void*, unsigned long, bool)+388)
  #07  pc 0x0000000000188ca0  /system/lib64/libandroid_runtime.so (int android_media_AudioRecord_readInArray<_jshortArray*>(_JNIEnv*, _jobject*, _jshortArray*, int, int, unsigned char)+232)
  #08  pc 0x00000000002ee1c0  /data/misc/apexdata/com.android.art/dalvik-cache/arm64/boot.oat (art_jni_trampoline+128)
  #09  pc 0x00000000020009f0  /memfd:jit-cache (android.media.AudioRecord.read+240)

用户提供的相关代码(在其他设备上运行正常,应用已有数百万下载量):

AudioRecord ar = new AudioRecord(MediaRecorder.AudioSource.MIC, iAudioSampleRate, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, N * 10);
...
_ar.startRecording();
...
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    iReadCount = _ar.read(buffer, 0, buffer.length, AudioRecord.READ_NON_BLOCKING);
} else {
    iReadCount = _ar.read(buffer, 0, buffer.length);
}

可能的崩溃原因

  • 三星定制音频服务的严格校验:崩溃栈显示在releaseBuffer阶段触发断言失败,说明三星对AudioFlinger的定制实现中,对缓冲区状态的校验比原生Android更严格。比如调用read时缓冲区未就绪、已被释放或状态异常,直接触发断言导致崩溃。
  • 非阻塞读的时序竞态:Android M及以上使用的READ_NON_BLOCKING模式,在三星设备上可能存在时序问题。比如startRecording后,AudioRecord尚未完全进入就绪状态就执行read,导致底层缓冲区操作异常。
  • 缓冲区大小不兼容:初始化时使用固定值N*10作为缓冲区大小,可能不符合三星设备音频硬件的要求(比如不是硬件帧大小的整数倍),导致后续读写时缓冲区状态混乱。
  • 生命周期管理疏漏:存在重复调用startRecording/stop,或者read操作时AudioRecord已被意外释放,导致Native层操作无效对象。

潜在解决办法

  • 增加就绪状态校验:调用read前,先通过getRecordingState()确认AudioRecord处于RECORDSTATE_RECORDING状态,避免在未就绪时执行读写操作。
  • 使用硬件兼容的缓冲区大小:用AudioRecord.getMinBufferSize()获取当前设备的最小缓冲区大小,以此为基准设置缓冲区(比如取其2倍或整数倍),替代固定值N*10。示例:
    int minBufferSize = AudioRecord.getMinBufferSize(iAudioSampleRate, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
    int bufferSize = minBufferSize * 2; // 保证缓冲区足够且符合硬件要求
    AudioRecord ar = new AudioRecord(MediaRecorder.AudioSource.MIC, iAudioSampleRate, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSize);
    
  • 优化读写模式:尝试在所有版本中统一使用阻塞读模式,或者针对三星设备单独禁用READ_NON_BLOCKING,验证是否是非阻塞模式导致的兼容性问题。
  • 强化生命周期管理:确保startRecording仅调用一次,read操作前AudioRecord未被release,使用完毕后正确调用stop()和release()释放资源;若出现异常,尝试重新初始化AudioRecord而非直接崩溃。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 23:42:22