前言:在使用uniapp开发中,遇见了这样一个问题:两个有音频的子页面,第一个页面打开音频正常,第二个页面的音频响不了,猜测是内存泄漏的原因。遂记录下解决方案。
一、解决过程
在开发安卓应用时引入了APP原生插件,在使用原生插件后,插件在子页面加载中比较慢,根据uniapp官方文档,使用uni.preloadPage来预加载使用了插件的子页面。
onLoad() {
uni.preloadPage({ url: "/pages/xxxx/childPage1" });
uni.preloadPage({ url: "/pages/xxxx/childPage2" });
}
这样写好后子页面确实会预加载,但是第二个子页面的音频就不能响了。一开认为是子页面离开时没有把音频组件销毁的原因,但是手动销毁后发现问题依旧,遂思考应该是uni.preloadPage导致的原因,因为在父页面onLoad时同时预加载两个子页面的onLoad和onReady,文档中已经告诉我们了:
注意事项
- App平台仅支持预加载 nvue 页面,执行页面预渲染,预载时触发生命周期
onLoad,onReady,不触发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会触发 onLoad,onReady,但是仍然遵守生命周期顺序。