在uni-app的APP端使用plus.screen.lockOrientation切换横竖屏后快速多次点击导航栏的返回按钮会偶尔出现闪退现象

在uni-app的APP端使用plus.screen.lockOrientation切换横竖屏后快速多次点击导航栏的返回按钮会偶尔出现闪退现象

开发环境 版本号 项目创建方式
Windows 11 HBuilderX

操作步骤:

  1. 创建usePageOrientation.ts文件
export function usePageOrientation() {  
  const lockLandscape = () => {  
    // #ifdef APP-PLUS  
    plus.screen.lockOrientation('landscape-primary')  
    // #endif  
  }  

  const restorePortrait = () => {  
    // #ifdef APP-PLUS  
    plus.screen.lockOrientation('portrait-primary')  
    // #endif  
  }  

  return {  
    lockLandscape,  
    restorePortrait,  
  }  
}
  1. 在a页面引入onShow中执行restorePortrait
import { usePageOrientation } from '@/hooks/usePageOrientation'  
const { lockLandscape, restorePortrait } = usePageOrientation()  
onShow(() => {  
  restorePortrait()  
})
  1. 从a页面跳转到b页面,页面设置为横屏
import { usePageOrientation } from '@/hooks/usePageOrientation'  
const { lockLandscape, restorePortrait } = usePageOrientation()  
onLoad((options: any) => {  
  lockLandscape()  
})

更多关于在uni-app的APP端使用plus.screen.lockOrientation切换横竖屏后快速多次点击导航栏的返回按钮会偶尔出现闪退现象的实战教程也可以访问 https://www.itying.com/category-93-b0.html

1 回复

更多关于在uni-app的APP端使用plus.screen.lockOrientation切换横竖屏后快速多次点击导航栏的返回按钮会偶尔出现闪退现象的实战教程也可以访问 https://www.itying.com/category-93-b0.html


这是一个典型的屏幕方向切换与页面生命周期冲突导致的闪退问题。在uni-app的APP端,plus.screen.lockOrientation会触发Webview的重绘和布局调整,此时如果快速操作导航栏返回按钮,容易引发以下问题:

  1. 线程竞争:屏幕方向切换是异步操作,而页面返回是同步的。当方向切换未完成时执行返回,可能导致Webview状态不一致。

  2. 内存访问冲突:横竖屏切换涉及Webview重建,此时频繁返回可能造成旧的Webview实例已被销毁但新的还未完全初始化。

  3. 生命周期混乱:onLoad和onShow中的方向切换与页面栈管理产生时序冲突。

解决方案:

  1. 添加防抖控制
let isSwitching = false
const lockLandscape = () => {
  if (isSwitching) return
  isSwitching = true
  plus.screen.lockOrientation('landscape-primary')
  setTimeout(() => { isSwitching = false }, 500)
}
  1. 在onReady中执行方向切换
onReady(() => {
  lockLandscape()
})
  1. 返回前恢复方向
onBackPress(() => {
  restorePortrait()
  // 不立即返回,等待方向切换完成
  setTimeout(() => {
    uni.navigateBack()
  }, 100)
  return true // 阻止默认返回行为
})
  1. 使用uni.addInterceptor拦截路由
uni.addInterceptor('navigateBack', {
  invoke(args) {
    restorePortrait()
    return new Promise(resolve => {
      setTimeout(() => {
        resolve(args)
      }, 150)
    })
  }
})
回到顶部