uni-app打测试包ios系统含视频页面播放闪退

uni-app打测试包ios系统含视频页面播放闪退

项目名称
产品分类 uniapp/App
PC开发环境操作系统 Windows
PC开发环境操作系统版本号 Windows 11 家庭中文版
HBuilderX类型 正式
HBuilderX版本号 4.76
手机系统 iOS
手机系统版本号 iOS 18
手机厂商 苹果
手机机型 14pro
页面类型 nvue
vue版本 vue2
打包方式 云端
项目创建方式 HBuilderX

操作步骤:

ios系统安装app,打开含有视频页面播放后,返回页面闪退

预期结果:

ios系统安装视频页面播放后正常返回

实际结果:

ios系统安装app,打开含有视频页面播放后,返回页面闪退

bug描述:

uniapp打测试包,ios系统安装,打开含有视频页面播放后,返回路由app闪退(继续跳转页面没问题)


更多关于uni-app打测试包ios系统含视频页面播放闪退的实战教程也可以访问 https://www.itying.com/category-93-b0.html

11 回复

4.83已修复

更多关于uni-app打测试包ios系统含视频页面播放闪退的实战教程也可以访问 https://www.itying.com/category-93-b0.html


升级最新 HBuilderX 4.82 alpha 试一下,如果标准基座可复现问题,请提供复现工程。

下载HBuilderX 4.82 alpha 打包还是会闪退

我试了一下,只有nvue页面播放视频返回会闪退

回复 Sokach_: 如果标准基座可复现问题,请提供复现工程

回复 DCloud_UNI_OttoJi: 我已经找到问题了,是9.30号更新的SDK造成的,应该是【修复 视频播放 video 静音模式播放后调整音量依旧无声音的Bug 】修复个的时候改到某个东西。导致不兼容了,麻烦查验一下

回复 DCloud_UNI_OttoJi: 4.81.2025091909-alpha 这个版本的问题 4.76版本正常

回复 Sokach_: 好的,我让相关同事看下

<template> <view class="page-container"> <view class="arrow_box" :class="scroll > 40 ? 'arrow_boxs' : ''"> <view class="arrow_img" @click="retur()"> <image class="arrow_img" src="../../static/fall.png" mode=""></image> </view> </view> <Swiper :info="detail"></Swiper> <view class="information" :style="{ paddingBottom: safeArea + 'px' }"> <view class="collection"> <view class="price-box" v-if="detail.minPrice !== detail.maxPrice"> <text class="price-symbol">¥</text> <text class="price-text">{{ detail.minPrice }}</text> <text style="color: #59a1d4">-</text> <text class="price-symbol">¥</text> <text class="price-text">{{ detail.maxPrice }}</text> </view> <view class="price-box" v-else> <text class="price-symbol">¥</text ><text class="price-text">{{ detail.minPrice }}</text> </view> </view> <view class="collection-name"> <text class="collection-name_text">{{ detail.name }}</text> </view> <view class="model-number" v-if="detail.sourceType === 0"> <text class="model-number_text" >型号:{{ productInfoDto.modelName }}</text > </view>
  <view class="collection-desc" v-if="detail.desc">  
    <text class="collection-desc_text">{{ detail.desc }}</text>  
  </view>  

  <view class="product-info">  
    <view class="info-item">  
      <text class="item-left">已选</text>  
      <view class="item-right">  
        <text class="item-right_text" @click="onSpecificationPopup(1)">  
          {{ selSpecText }} ></text  
        >  
      </view>  
    </view>  
    <view class="info-item">  
      <text class="item-left">运费</text>  
      <view class="item-right">  
        <text  
          class="item-right_text"  
          v-if="logisticsDeliveryDto.isFreeShipping === 0"  
          >包邮</text  
        >  
        <text class="item-right_text" v-else  
          >¥{{ logisticsDeliveryDto.shippingUnitPrice }}</text  
        >  
      </view>  
    </view>  
    <view class="info-item">  
      <text class="item-left">商品评价</text>  
      <view class="item-right">  
        <text class="item-right_text" @click="toEvaluatePage">  
          {{ commentCount ? commentCount + "条评价" : "暂无评价" }} >  
        </text>  
      </view>  
    </view>  
  </view>  

  <view class="storefront">  
    <view style="flex-direction: row; align-items: center">  
      <view class="storefro">  
        <text class="storefront-name">{{ detail.brandName }}</text>  
        <text class="storefro-text">共有{{ brandCount }}件商品在售</text>  
      </view>  
    </view>  
    <view class="detail" @click="Introdudetail(detail.brandId)">  
      <text class="detail-text">了解详情 ></text>  
    </view>  
  </view>  
  <!-- 产品详情和参数配置 -->  
  <Info :info="detail"></Info>  
</view>  
<!-- 信息END -->  
<!-- footer -->  
<view  
  class="footer"  
  :style="{ paddingBottom: safeArea ? safeArea + 'px' : '24rpx' }"  
>  
  <view class="footer-left">  
    <view class="kefu" @click="openKeFu">  
      <image class="kefu-icon" src="../../static/kefu.png" alt=""></image>  
      <text class="kefu-text">客服</text>  
    </view>  
    <view class="cart" @click="toCart">  
      <view style="width: 80rpx; align-items: center">  
        <image class="cart-icon" src="../../static/cart.png" alt=""></image>  
        <text class="cart-text">购物车</text>  
      </view>  
      <view class="cart-num">  
        <text class="cart-num_text">{{  
          cartCount > 99 ? "99+" : cartCount  
        }}</text>  
      </view>  
    </view>  
  </view>  
  <view class="footer-right">  
    <view class="btn-item join-cart" @click="onSpecificationPopup(2)">  
      <text class="join-cart_text">加入购物车</text>  
    </view>  
    <view class="btn-item buy-btn" @click="onSpecificationPopup(3)">  
      <text class="buy-btn_text">立即购买</text>  
    </view>  
  </view>  
</view>  
<goods-specification  
  ref="specificationRef"  
  :goodsSpecDtoList="goodsSpecDtoList"  
  :goodsSpecSkuDtoList="goodsSpecSkuDtoList"  
  @specChange="onSpecChange"  
>  
  <template v-slot:footer-btn>  
    <view class="specification-footer" v-if="specificationType === 1">  
      <view class="footer-btn join-cart_footer" @click="joinCart">  
        <text style="color: #59a1d4; font-size: 32rpx; font-weight: bold"  
          >加入购物车</text  
        >  
      </view>  
      <view class="footer-btn buy-btn_footer" @click="onBuy">  
        <text style="color: #fff; font-size: 32rpx; font-weight: bold"  
          >立即购买</text  
        >  
      </view>  
    </view>  
    <view class="confirm-btn" @click="specificationConfirm" v-else>  
      <text class="confirm-btn_text">确定</text>  
    </view>  
  </template>  
</goods-specification>  
</view> </template> <script> import { openKeFu, calcSafeArea } from "@/utils/index"; import GoodsSpecification from "@/components/GoodsSpecification/index.nvue"; import Info from "./components/Info.nvue"; import Swiper from "./components/Swiper.nvue"; export default { components: { GoodsSpecification, Info, Swiper, }, data() { return { // 商品详情 detail: {}, // 产品信息 productInfoDto: {}, // 物流信息 logisticsDeliveryDto: {}, // 规格列表 goodsSpecDtoList: [], // 规格对应商品信息 goodsSpecSkuDtoList: [], top: "", isFolp: false, // 页面滚动条位置 scroll: 0, statusBarHeight: 0, specificationType: 1, // 1-已选(展示加入购物车、立即购买)2、加入购物车 3、立即购买 selSpecText: "请选择规格", selectSpecInfo: null, // 选中的规格信息 num: 1, // 选择的商品数量 goodsSpecSkuId: null, // 从购物车带过来的已选规格信息 commentCount: 0, // 评论总数 brandCount: 0, // 品牌下的在售商品数 cartCount: 0, // 购物车总数 safeArea: calcSafeArea(), }; }, onLoad(option) { // 商品详情id this.id = option.id; if (option.goodsSpecSkuId) { this.goodsSpecSkuId = option.goodsSpecSkuId; } option.num && (this.num = Number(option.num)); this.goodsDetail(); }, onShow() { this.getCommentCount(); if (uni.getStorageSync("token")) { this.getCartCount(); } }, // 监听滚动条 onPageScroll(e) { this.scroll = e.scrollTop; }, methods: { openKeFu, // 商品详情 async goodsDetail() { try { const data = { // productId:24 goodsId: this.id, }; const res = await uni.$api.goods.goodsDetail(data); this.detail = res; this.productInfoDto = res.productInfoDto || {}; this.logisticsDeliveryDto = res.logisticsDeliveryDto || {}; // this.propertyGroupList = res.productInfoDto?.propertyGroupList.slice(0, 2) || []; this.goodsSpecDtoList = res.goodsSpecDtoList || []; this.goodsSpecSkuDtoList = res.goodsSpecSkuDtoList || []; setTimeout(() => { // 处理购物车带过来的已选规格 if (this.goodsSpecSkuId) { this.$refs.specificationRef.handleCartSpec( this.goodsSpecSkuId, this.num ); } }); // 获取品牌下的在售商品数 this.getBrandCount(res.brandId); } catch (err) { console.log(err); } }, // 获取品牌在售商品数 async getBrandCount(brandId) { const res = await uni.$api.goods.obtainGoodsCount({ brandId }); this.brandCount = res; }, // 获取商品评价总数 async getCommentCount() { const data = { sourceId: this.id, sourceType: 2, // 文章类型 0:为文章表 1:视频表 2:商品表 pid: 0, }; const res = await uni.$api.goods.userCommentNumber(data); this.commentCount = res || 0; }, // 获取购物车总数 async getCartCount() { const res = await uni.$api.goods.cartGoodsCount(); this.cartCount = res || 0; }, // 返回 retur() { uni.navigateBack(); }, // 了解详情 Introdudetail(brandId) { uni.navigateTo({ url: "/pagesProst/Introduction/Introduction?id=" + brandId, }); }, // 打开规格弹窗 onSpecificationPopup(type) { this.specificationType = type; this.$refs.specificationRef.open(); }, // 规则选择确认 specificationConfirm() { if (this.specificationType === 2) { // 加入购物车 this.joinCart(); } else if (this.specificationType === 3) { // 立即购买 this.onBuy(); } }, // 检查登录 checkLogin() { if (!uni.getStorageSync("token")) { // uni.$emit("warn-show", { // content: "检测您还未登录,请先登录", // confirmText: "去登录", // closeable:true, // confirm: () => { // uni.removeStorageSync("token"); // // 去登录 // uni.navigateTo({ // url: "/pages/Login/index" // }); // } // }); uni.showToast({ title: "检测您还未登录,请先登录", icon: "none", }); return false; } return true; }, // 加入购物车 async joinCart() { this.$refs.specificationRef.close(); if (!this.checkLogin()) return; try { if (this.num == 0) { uni.showToast({ title: "加入购物车失败,至少购买1件商品", icon: "none", }); return; } // 判断库存 if (this.num > this.selectSpecInfo.storeCount) { uni.showToast({ title: "库存不足,请修改购买数量", icon: "none", }); return; } const data = { goodsId: this.detail.id, goodsSpecSkuId: this.selectSpecInfo.id, num: this.num, }; await uni.$api.goods.addGoodsCart(data); uni.showToast({ title: "加入成功", icon: "none", }); uni.$emit("updateCartList"); this.getCartCount(); uni.$tracker.trackClickEvent("addCart_click", "加入购物车", { ...this.detail, ...data, }); } catch (err) { console.log(err); } }, // 立即购买 onBuy() { this.$refs.specificationRef.close(); if (!this.checkLogin()) return; if (this.num > this.selectSpecInfo.storeCount) { uni.showToast({ title: "库存不足,请修改购买数量", icon: "none", }); return; } uni.navigateTo({ url: `/pagesProst/confirmOrder/confirmOrder?goodsSpecSkuId=${this.selectSpecInfo.id}&num=${this.num}&goodsId=${this.id}`, }); // uni.navigateTo({ // url: `/secondhand/pages/confirmBuy/index?goodsSpecSkuId=${this.selectSpecInfo.id}&num=${this.num}&goodsId=${this.id}` // }); }, // 选择规格change onSpecChange(selSpec, num, source) { this.selectSpecInfo = selSpec; this.num = num; const skuNameList = selSpec.skuName.split("+"); if (skuNameList[1]) { this.selSpecText = `${skuNameList[0]}(${skuNameList[1]})*${num}`; } else { this.selSpecText = `${skuNameList[0]}*${num}`; } }, // handleSelSpecText() { // let skuNameList = this.$refs.specificationRef.skuNameList; // let num = this.$refs.specificationRef.num; // this.selSpecText = `${skuNameList[0]}(${skuNameList[1]})*${num}`; // this.$refs.specificationRef.close(); // }, // 评价页面 toEvaluatePage() { uni.navigateTo({ url: "/pagesProst/goodsEvaluate/goodsEvaluate?id=" + this.detail.id, }); }, // 去购物车 toCart() { uni.navigateTo({ url: "/pagesProst/cart/cart", }); }, }, }; </script> <style scoped> [@import](/user/import) "./index.css"; </style>

无法登陆

这是一个典型的iOS视频播放器内存释放问题。在nvue页面中使用video组件时,iOS系统对视频资源的释放处理较为严格,返回页面时若未正确销毁播放器实例,容易引发内存访问异常导致闪退。

解决方案:

  1. 生命周期管理:在页面的onUnloadbeforeDestroy生命周期中显式销毁视频播放器:
onUnload() {
    this.videoContext && this.videoContext.destroy()
}
  1. 暂停播放:在onHideonBackPress中先暂停视频:
onBackPress() {
    this.videoContext && this.videoContext.pause()
}
  1. 视频组件配置:确保video组件设置了正确的object-fit属性,避免渲染异常:
<video 
    ref="videoRef"
    src="..."
    object-fit="contain"
    controls
></video>
回到顶部