uni-app 在安卓12、安卓15中uni.navigateTo的events中调用uni.getStorageSync返回undefined

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

uni-app 在安卓12、安卓15中uni.navigateTo的events中调用uni.getStorageSync返回undefined

产品分类

uniapp/小程序

开发环境信息

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

示例代码

通用工具类代码/common/js/storage.js

export function getToken() {  
  return uni.getStorageSync("authorization")  
}  

export function setToken(data) {  
  uni.setStorageSync("authorization", data)  
}  

export function removeToken() {  
  uni.removeStorageSync("authorization")  
}  

export function getSearchFields() {  
  return uni.getStorageSync("searchFields")  
}  

export function setSearchFields(data) {  
  uni.setStorageSync("searchFields", data)  
}

主页代码/pages/demo/demo.vue

<template>  
  <view>  
    <button type="primary" @click="handleClick">详情</button>  
  </view>  
</template>  

<script>  
  import {  
    getToken,  
    setToken  
  } from "@/common/js/storage.js"  

  export default {  
    data() {  
      return {}  
    },  
    onShow() {  
      setToken("123456")  
    },  
    methods: {  
      handleClick(item) {  
        uni.navigateTo({  
          url: `/pages/demo/detail`,  
          events: {  
            refresh: () => {  
              console.log(getToken())  
            },  
          },  
          success: (res) => {}  
        })  
      }  
    },  
  }  
</script>  

<style lang="scss" scoped>  
  .item-box {  
    width: 100%;  
    padding: 6px 4px;  
    border-bottom: 1px solid rgba(0, 0, 0, .3);  
    box-sizing: border-box;  

    .item-box-subtitle {  
      color: $uni-info;  
    }  
  }  
</style>

详情页代码 /pages/demo/detail.vue

<template>  
  <view>  
    <button type="primary" @click="handleClick">返回</button>  
  </view>  
</template>  

<script>  
  export default {  
    data() {  
      return {}  
    },  
    methods: {  
      handleClick() {  
        uni.navigateBack({  
          success: () => {  
            this.getOpenerEventChannel().emit("refresh");  
          }  
        });  
      }  
    },  
  }  
</script>  

<style lang="scss" scoped>  
</style>

操作步骤

在主页/pages/demo/demo点击详情按钮后,再点击返回,就会在控制台打印数据。

预期结果

控制台输出123456

实际结果

在oneplus的安卓12版本、xiaomi的安卓12和15版本控制台会输出undefined。但是小程序开发工具的模拟器、iphone xs的ios17.3.1会输出123456。

bug描述

在安卓12、安卓15中uni.navigateTo的events中调用uni.getStorageSync为undefined。 在小程序开发者工具、iphone xs的ios17.3.1输出就正常。

Image 1 Image 2


1 回复

在uni-app中,uni.navigateTo 方法用于页面跳转,并且在跳转后可以监听目标页面的特定事件。然而,在Android 12和Android 15中,如果在 events 回调函数中调用 uni.getStorageSync 方法返回 undefined,这通常是由于页面跳转与存储同步操作之间的时机或上下文问题导致的。

以下是一个简化的代码案例,展示如何在 uni.navigateToevents 中安全地访问存储数据。我们将通过事件通信机制来确保数据在正确的时机被访问和处理。

主页面(Page A)代码

// Page A
uni.navigateTo({
    url: '/pages/PageB/PageB',
    events: {
        // 监听来自 PageB 的事件
        getDataFromB: function(data) {
            console.log('Received data from PageB:', data);
            // 在这里,我们不直接在events中调用getStorageSync
        },
        // 可以添加一个方法来初始化数据
        initStorageData: function() {
            // 假设我们在这里已经存储了数据
            const storedData = uni.getStorageSync('myData');
            // 将数据传递给PageB(如果需要)
            uni.getCurrentPages()[0].$vm.sendDataToB(storedData);
        },
    },
    success: function() {
        // 触发初始化存储数据的操作
        this.events.initStorageData();
    }
});

目标页面(Page B)代码

// Page B
Page({
    data: {
        receivedData: null,
    },
    onLoad: function(options) {
        // 监听来自 Page A 的事件
        const events = getCurrentPages()[0].getOpenerEventChannel();
        events.on('sendDataFromA', this.handleDataFromA);
    },
    methods: {
        handleDataFromA(data) {
            this.setData({
                receivedData: data,
            });
            // 触发事件通知 Page A 数据已接收
            const events = getCurrentPages()[0].getOpenerEventChannel();
            events.emit('getDataFromB', { status: 'success', data: this.data.receivedData });
        },
        // 假设有一个方法用于接收外部数据(如从 Page A 发送)
        sendDataToB(data) {
            this.setData({ receivedData: data });
        }
    }
});

注意事项

  1. 事件通信:通过事件通信机制,在Page A和Page B之间传递数据,而不是直接在 events 回调中访问存储。
  2. 数据存储与访问:确保在数据被访问之前,数据已经被正确存储,并且存储操作没有失败。
  3. 页面生命周期:理解页面的生命周期,确保在正确的时机进行数据存储和访问操作。

上述代码提供了一种通过事件通信来间接处理存储数据的方法,从而避免了在 events 回调中直接调用 uni.getStorageSync 可能导致的上下文问题。

回到顶部