uniapp中多个页面音频失效的问题

318 阅读2分钟

前言:在使用uniapp开发中,遇见了这样一个问题:两个有音频的子页面,第一个页面打开音频正常,第二个页面的音频响不了,猜测是内存泄漏的原因。遂记录下解决方案。

一、解决过程

在开发安卓应用时引入了APP原生插件,在使用原生插件后,插件在子页面加载中比较慢,根据uniapp官方文档,使用uni.preloadPage来预加载使用了插件的子页面。

onLoad() {
    uni.preloadPage({ url: "/pages/xxxx/childPage1" });
    uni.preloadPage({ url: "/pages/xxxx/childPage2" });
}

这样写好后子页面确实会预加载,但是第二个子页面的音频就不能响了。一开认为是子页面离开时没有把音频组件销毁的原因,但是手动销毁后发现问题依旧,遂思考应该是uni.preloadPage导致的原因,因为在父页面onLoad时同时预加载两个子页面的onLoadonReady文档中已经告诉我们了:

注意事项

  1. App平台仅支持预加载 nvue 页面,执行页面预渲染,预载时触发生命周期 onLoadonReady,不触发 onShow

因为子页面创建音频组件,需要预先createInnerAudioContext

// 通常都是onLoad或者onReady中:
onLoad() {
    this.innerAudioContext = uni.createInnerAudioContext();
    this.innerAudioContext.autoplay = false;
    this.innerAudioContext.loop = false;
    this.innerAudioContext.src = "xxxxxxxx";
    this.innerAudioContext.volume = 0.1;
}

遂修改预加载逻辑,改为父页面跳转前进行预加载,虽然不如在onLoad中,但也足够快了。

jumpTo() {
    uni.preloadPage({ url: "/pages/xxxx/childPage1" });
    uni.navigateTo({
        url: "/pages/xxxx/childPage1",
        fail: (err) => {
            console.log(err);
        },
    });
}

此时音频问题已经解决了,这个时候为了页面的观感更好一些,在使用了APP原生插件需要初始化时,建议不要在子页面onLoad时初始化,可以把插件的init函数写在onReady中,虽然uni.preloadPage会触发 onLoadonReady,但是仍然遵守生命周期顺序。