uni-app 最新版本4.45在打包微信小程序时uni.getSystemInfoSync并非同步获取设备信息

发布于 1周前 作者 itying888 来自 Uni-App

uni-app 最新版本4.45在打包微信小程序时uni.getSystemInfoSync并非同步获取设备信息

产品分类

uniapp/小程序/微信

开发环境信息

项目 信息
PC开发环境操作系统 Windows
HBuilderX类型 正式
HBuilderX版本号 4.45
第三方开发者工具版本号 1.06.2407120
基础库版本号 3.14
项目创建方式 HBuilderX

示例代码

import { ref, reactive, toRefs } from "vue";  
import { useStore } from "vuex";  
import _isFunction from "lodash/isFunction";  

function getSystemInfo() {  
  if (uni.globalSystemInfo && !uni.globalSystemInfo.ios) {  
    return uni.globalSystemInfo;  
  } else {  
    // h5环境下忽略navbar  
    if (!_isFunction(uni.getSystemInfoSync)) {  
      return null;  
    }  
    let systemInfo = uni.getSystemInfoSync() || {  
      model: "",  
      system: "",  
    };  
    let ios = !!(systemInfo.system.toLowerCase().search("ios") + 1);  
    let rect;  
    try {  
      rect = uni.getMenuButtonBoundingClientRect  
        ? uni.getMenuButtonBoundingClientRect()  
        : null;  
      if (rect === null) {  
        throw "getMenuButtonBoundingClientRect error";  
      }  
      //取值为0的情况  有可能width不为0 top为0的情况  
      if (!rect.width || !rect.top || !rect.left || !rect.height) {  
        throw "getMenuButtonBoundingClientRect error";  
      }  
    } catch (error) {  
      let gap = ""; //胶囊按钮上下间距 使导航内容居中  
      let width = 96; //胶囊的宽度  
      if (systemInfo.platform === "android") {  
        gap = 8;  
        width = 96;  
      } else if (systemInfo.platform === "devtools") {  
        if (ios) {  
          gap = 5.5; //开发工具中ios手机  
        } else {  
          gap = 7.5; //开发工具中android和其他手机  
        }  
      } else {  
        gap = 4;  
        width = 88;  
      }  
      if (!systemInfo.statusBarHeight) {  
        //开启wifi的情况下修复statusBarHeight值获取不到  
        systemInfo.statusBarHeight =  
          systemInfo.screenHeight - systemInfo.windowHeight - 20;  
      }  
      rect = {  
        //获取不到胶囊信息就自定义重置一个  
        bottom: systemInfo.statusBarHeight + gap + 32,  
        height: 32,  
        left: systemInfo.windowWidth - width - 10,  
        right: systemInfo.windowWidth - 10,  
        top: systemInfo.statusBarHeight + gap,  
        width: width,  
      };  
      console.log("error", error);  
      console.log("rect", rect);  
    }  

    let navBarHeight = "";  
    if (!systemInfo.statusBarHeight) {  
      //开启wifi和打电话下  
      systemInfo.statusBarHeight =  
        systemInfo.screenHeight - systemInfo.windowHeight - 20;  
      navBarHeight = (function () {  
        let gap = rect.top - systemInfo.statusBarHeight;  
        return 2 * gap + rect.height;  
      })();  

      systemInfo.statusBarHeight = 0;  
      systemInfo.navBarExtendHeight = 0; //下方扩展4像素高度 防止下方边距太小  
    } else {  
      navBarHeight = (function () {  
        let gap = rect.top - systemInfo.statusBarHeight;  
        return systemInfo.statusBarHeight + 2 * gap + rect.height;  
      })();  
      if (ios) {  
        systemInfo.navBarExtendHeight = 4; //下方扩展4像素高度 防止下方边距太小  
      } else {  
        systemInfo.navBarExtendHeight = 0;  
      }  
    }  

    systemInfo.navBarHeight = navBarHeight; //导航栏高度不包括statusBarHeight  
    systemInfo.capsulePosition = rect; //右上角胶囊按钮信息bottom: 58 height: 32 left: 317 right: 404 top: 26 width: 87 目前发现在大多机型都是固定值 为防止不一样所以会使用动态值来计算nav元素大小  
    systemInfo.ios = ios; //是否ios  
    uni.globalSystemInfo = systemInfo; //将信息保存到全局变量中,后边再用就不用重新异步获取了  
    //console.log('systemInfo', systemInfo);  
    return systemInfo;  
  }  
}  

let globalSystemInfo = getSystemInfo();  
console.log(globalSystemInfo, "globalSystemInfo");  

const store = useStore();  
const props = defineProps({  
  extClass: "",  
  background: { type: String, default: "#fff" }, //导航栏背景  
  color: {  
    type: String,  
    default: "#333",  
  },  
  title: {  
    type: String,  
    default: "",  
  },  
  searchText: {  
    type: String,  
    default: "点我搜索",  
  },  
  searchBar: {  
    type: Boolean,  
    default: false,  
  },  
  back: {  
    type: Boolean,  
    default: true,  
  },  
  home: {  
    type: Boolean,  
    default: false,  
  },  
  iconTheme: {  
    type: String,  
    default: "",  
  },  
});  

const setStyle = (systemInfo) => {  
  const {  
    statusBarHeight,  
    navBarHeight,  
    capsulePosition,  
    navBarExtendHeight,  
    ios,  
    windowWidth,  
  } = systemInfo;  
  const { back, home, title, color } = props;  
  console.log(back,systemInfo, "back");  

  let rightDistance = windowWidth - capsulePosition.right; //胶囊按钮右侧到屏幕右侧的边距  
  console.log(rightDistance, "rightDistance");  

  let leftWidth = windowWidth - capsulePosition.left; //胶囊按钮左侧到屏幕右侧的边距  

  let navigationbarinnerStyle = [  
    `color:${color}`,  
    `height:${navBarHeight + navBarExtendHeight}px`,  
    `padding-top:${statusBarHeight}px`,  
    `padding-right:${leftWidth}px`,  
    `padding-bottom:${navBarExtendHeight}px`,  
  ].join(";");  

  let navBarLeft = [];  
  if ((back && !home) || (!back && home)) {  
    navBarLeft = [  
      `width:${capsulePosition.width}px`,  
      `height:${capsulePosition.height}px`,  
      `margin-left:0px`,  
      `margin-right:${rightDistance}px`,  
    ].join(";");  
  } else if ((back && home) || title) {  
    navBarLeft = [  
      `width:${capsulePosition.width}px`,  
      `height:${capsulePosition.height}px`,  
      `margin-left:${rightDistance}px`,  
    ].join(";");  
  } else {  
    navBarLeft = [`width:auto`, `margin-left:0px`].join(";");  
  }  

  const topHeight = navBarHeight + navBarExtendHeight;  
  console.log(topHeight, "topHeight");  

  store.commit("global/SET_NAV_BAR_HEIGHT", topHeight);  
  return {  
    navigationbarinnerStyle,  
    navBarLeft,  
    navBarHeight,  
    capsulePosition,  
    navBarExtendHeight,  
    ios,  
    rightDistance,  
  };  
};  

const state = reactive({  
  configStyle: setStyle(globalSystemInfo),  
});  

const { configStyle } = toRefs(state);  
const {  
  navigationbarinnerStyle,  
  navBarLeft,  
  navBarHeight,  
  capsulePosition,  
  navBarExtendHeight,  
  ios,  
  rightDistance,  
} = state.configStyle;  

console.log(navBarLeft, "navBarLeft");  

const handleBackClick = () => {  
  if (_isFunction(props.onBack)) {  
    props.onBack();  
  } else {  
    const pages = getCurrentPages();  
    if (pages.length >= 2) {  
      uni.navigateBack({  
        delta: props.delta,  
      });  
    }  
  }  
};  

const handleGoHomeClick = () => {  
  if (_isFunction(props.onHome)) {  
    props.onHome();  
  }  
};  

const handleSearchClick = () => {  
  if (_isFunction(props.onSearch)) {  
    props.onSearch();  
  }  
};

操作步骤

编译运行

预期结果

编译运行获取 setStyle 函数中 systemInfo 为一个设备类型对象

实际结果

编译运行获取 setStyle 函数中 systemInfo 为一个 Promise 函数

bug 描述

运行编译到小程序后,获取设备信息为 Promise 函数


2 回复

感谢反馈,此bug并非是getSystemInfoSync的Bug。问题出在下面这几行代码
if (uni.globalSystemInfo && !uni.globalSystemInfo.ios) { return uni.globalSystemInfo; }
目前这个bug会导致访问uni上不存在的属性也会返回一个方法,预计在4.51-alpha(下个alpha)修复


在uni-app最新版本4.45中,如果你遇到uni.getSystemInfoSync并未按预期同步获取设备信息的问题,这可能是由于多种原因导致的,比如API的调用时机、缓存机制或者是框架内部的bug。不过,通常uni.getSystemInfoSync应当是一个同步调用,用于立即获取设备信息。

为了确保你能够正确获取设备信息,并且在遇到异步行为时有一个替代方案,下面提供一个示例代码,展示如何使用uni.getSystemInfoSync以及如何在需要时回退到异步方法uni.getSystemInfo

示例代码

// 使用同步方法获取设备信息
try {
    const systemInfo = uni.getSystemInfoSync();
    console.log('同步获取设备信息成功:', systemInfo);
    // 在这里使用获取到的设备信息
} catch (error) {
    console.error('同步获取设备信息失败:', error);
    // 如果同步方法失败,尝试使用异步方法
    uni.getSystemInfo({
        success: (res) => {
            console.log('异步获取设备信息成功:', res);
            // 在这里使用异步获取到的设备信息
        },
        fail: (err) => {
            console.error('异步获取设备信息失败:', err);
            // 处理获取设备信息失败的逻辑
        }
    });
}

注意事项

  1. 错误处理:在同步调用失败时,使用try...catch结构捕获异常,并尝试异步调用。
  2. API调用时机:确保你的代码在合适的生命周期钩子或事件处理函数中调用这些API,避免在组件未完全加载时调用导致失败。
  3. uni-app和微信小程序的兼容性:检查uni-app和微信小程序的官方文档,确认当前使用的API版本和调用方式是否符合最新规范。
  4. 缓存机制:理解并考虑uni-app或微信小程序的缓存机制,这可能会影响你获取设备信息的实时性。
  5. 框架和依赖更新:确保你的uni-app框架和所有相关依赖都是最新版本,以避免已知的bug或不兼容问题。

通过上述代码示例和注意事项,你应该能够在大多数情况下正确获取设备信息,同时处理可能的异常情况。如果问题依旧存在,建议查阅uni-app的官方社区或提交issue寻求官方支持。

回到顶部