HarmonyOS鸿蒙Next中音频播放软件在被其他应用音频打断时闪退问题

HarmonyOS鸿蒙Next中音频播放软件在被其他应用音频打断时闪退问题 crash日志栈顶显示为

OHOS::AudioStandard::OHAudioRendererCallback::OnInterrupt (OHOS::AudioStandard::InterruptEvent const&) +64)

5 回复

从API version 12开始不再推荐使用OH_AudioRenderer_Callbacks的方式设置音频回调函数了,推荐分别使用新接口回调类型替代:OH_AudioRenderer_OnWriteDataCallbackOH_AudioRenderer_OutputDeviceChangeCallbackOH_AudioRenderer_OnInterruptCallback 以及 OH_AudioRenderer_OnErrorCallback

如还需使用该接口,使用以下方式解决:

方式1:请确保OH_AudioRenderer_Callbacks的每一个回调都被自定义的回调方法空指针初始化。

// 自定义写入数据函数。
int32_t MyOnWriteData(
    OH_AudioRenderer* renderer,
    void* userData,
    void* buffer,
    int32_t length)
{
    // 将待播放的数据,按length长度写入buffer。
    return 0;
}
// 自定义音频中断事件函数。
int32_t MyOnInterruptEvent(
    OH_AudioRenderer* renderer,
    void* userData,
    OH_AudioInterrupt_ForceType type,
    OH_AudioInterrupt_Hint hint)
{
    // 根据type和hint表示的音频中断信息,更新播放器状态和界面。
    return 0;
}
OH_AudioRenderer_Callbacks callbacks;
// 配置回调函数,如果需要监听,则赋值。
callbacks.OH_AudioRenderer_OnWriteData = MyOnWriteData;
callbacks.OH_AudioRenderer_OnInterruptEvent = MyOnInterruptEvent;
// (必选)无触发回调场景,使用空指针初始化。从API version 11开始,开发者如果需要监听设备变化,可直接使用OH_AudioRenderer_OutputDeviceChangeCallback替代。
callbacks.OH_AudioRenderer_OnStreamEvent = nullptr;
// (必选)如果不需要监听,使用空指针初始化。
callbacks.OH_AudioRenderer_OnError = nullptr;

方式2:使用前,初始化并清零结构体。

// 自定义写入数据函数。
int32_t MyOnWriteData(
OH_AudioRenderer* renderer,
void* userData,
void* buffer,
int32_t length)
{
// 将待播放的数据,按length长度写入buffer。
return 0;
}
// 自定义音频中断事件函数。
int32_t MyOnInterruptEvent(
OH_AudioRenderer* renderer,
void* userData,
OH_AudioInterrupt_ForceType type,
OH_AudioInterrupt_Hint hint)
{
// 根据type和hint表示的音频中断信息,更新播放器状态和界面。
return 0;
}
OH_AudioRenderer_Callbacks callbacks;

// 使用前,初始化并清零结构体。
memset(&callbacks, 0, sizeof(OH_AudioRenderer_Callbacks));

// 配置需要的回调函数。
callbacks.OH_AudioRenderer_OnWriteData = MyOnWriteData;
callbacks.OH_AudioRenderer_OnInterruptEvent = MyOnInterruptEvent;

更多关于HarmonyOS鸿蒙Next中音频播放软件在被其他应用音频打断时闪退问题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


感谢!

尊敬的开发者您好,小艺建议问题与建议反馈路径:

方式一:长按桌面底部的小艺导航条 > 上滑呼出全屏页面 > 点击左上角的返回键 > 右上角个人头像 > 帮助与客服 > 问题与建议 > 问题类型选择小艺建议,填写描述,勾选最下面的共享日志 > 点击提交即可。

方式二:点击设置 > 小艺 > 小艺建议 > 右上角四个点 > 问题与建议 > 问题类型选择小艺建议,填写描述,勾选最下面的共享日志 >点击提交即可。

音频播放闪退通常因未正确监听音频焦点变化。需使用 AVPlayerAudioRenderer 注册 onAudioInterrupt 回调,并在中断事件(如 AUDIO_INTERRUPT_TYPE_BEGIN)中暂停播放并释放资源,中断恢复时再重建。避免在回调内执行耗时操作或未处理空对象。

崩溃栈停在 OHAudioRendererCallback::OnInterrupt,说明应用在收到音频打断事件时发生了内存访问异常。常见原因是回调内部异步操作了 AudioRenderer 对象,而该对象已被提前释放或重置。在 HarmonyOS Next 中,打断回调可能在系统线程中触发,直接在其中调用 Release()Stop() 可能导致对象生命周期失控。

可这样修复:在 OnInterrupt 中仅设置状态标记或调用 Pause(),并通过消息队列或 EventHandler 将实际释放操作投递到安全线程执行,确保 AudioRenderer 实例在回调返回前始终有效。示例:

void OnInterrupt(const InterruptEvent &event) override {
    if (event.eventType == INTERRUPT_EVENT_BEGIN) {
        renderer_->Pause();
        auto handler = OHOS::AppExecFwk::EventHandler::Current();
        if (handler) {
            handler->PostTask([this]() {
                renderer_->Release();
            });
        }
    }
}

同时检查 SetInterruptCallback 是否已正确注册,避免使用裸指针持有 AudioRenderer,改用 std::shared_ptr 或确保回调生命周期内对象不会析构。

回到顶部