uni.getsysteminfosync()是app端最稳的获取方式,同步阻塞调用,启动完成后立即返回结果,适合初始化阶段直接取值;screenwidth/screenheight为物理屏幕总像素,windowwidth/windowheight为可渲染区域尺寸,pixelratio×160可估算dpi但存在偏差,仅适用于资源分级与rem计算。

uni.getSystemInfoSync() 是 App 端最稳的获取方式
在 App(iOS/Android 打包)环境下,uni.getSystemInfoSync() 比异步版更可靠——它不依赖网络或运行时状态,只要 App 启动完成就能立即返回结果,且不会因生命周期时机错位导致 this 失效或值为空。
注意:uni.getSystemInfo() 异步调用在某些低端 Android 设备上偶有回调丢失,尤其在 onLoad 早期触发时;而 uni.getSystemInfoSync() 是同步阻塞调用,适合初始化阶段直接取值。
-
screenWidth/screenHeight:物理屏幕总像素尺寸(含状态栏、导航栏) -
windowWidth/windowHeight:可渲染区域尺寸(排除顶部状态栏、底部虚拟按键等) -
pixelRatio:设备像素比(DPR),非 DPI,但可用于换算(见下条)
pixelRatio × 160 ≈ 实际 DPI,但仅作参考
UniApp 不直接暴露 dpi 字段,官方约定用 pixelRatio * 160 估算 DPI(因 Android mdpi 基准为 160dpi)。这个换算在多数场景够用,但要注意:
- iOS 设备(如 iPhone 15 Pro)
pixelRatio为 3,算得 480dpi,实际标称约 460ppi —— 存在合理偏差 - 部分华为/小米机型(尤其 HarmonyOS)返回的
pixelRatio可能被系统缩放策略干预(如“字体大小设为大号”时仍返回 2.75 而非真实硬件 DPR) - 不要用该值做精确物理尺寸测量(如 1cm 框),只用于资源加载分级(@2x/@3x 图)、rem 基准计算等逻辑适配
windowWidth 和 screenWidth 在 App 端差异明显
App 打包后,screenWidth 和 windowWidth 常不一致,这点和 H5 或小程序不同。典型表现:
- Android 全面屏手机:状态栏 + 底部导航栏占用空间 →
screenWidth= 1080,windowWidth≈ 1020 - iOS 安全区域(safeArea)影响:若未开启“沉浸式”,
windowHeight会扣除状态栏高度(statusBarHeight) - 横屏时
deviceOrientation字段才为"landscape",此时screenWidth和screenHeight数值互换,但windowWidth始终是当前可视宽度
做全屏布局时,优先用 windowWidth / windowHeight;做截图、Canvas 渲染或原生插件交互时,才需 screenWidth / screenHeight。
避免在 onLaunch 里直接调用 getSystemInfoSync
onLaunch 触发极早,部分 Android 原生容器尚未就绪,此时调用 uni.getSystemInfoSync() 可能返回默认值(如 pixelRatio: 1,screenWidth: 360),后续再调就正常了。
稳妥做法:
- 放在
App.vue的mounted钩子中(确保 Vue 实例已挂载) - 或在首个页面的
onLoad中调用(此时 App 容器已稳定) - 若必须在启动期使用,加一层 fallback:先取 sync 值,50ms 后再异步重取一次,取更合理的那个
真机调试时务必在 iOS 和主流 Android 品牌(华为、小米、OPPO、vivo)上验证数值是否合理,别只信模拟器输出。











