uni-app 手机点击home键程序后台运行 再次点击进入时 loading 图标显示不消失

uni-app 手机点击home键程序后台运行 再次点击进入时 loading 图标显示不消失

产品分类:

uniapp/App

PC开发环境操作系统:

Windows

PC开发环境操作系统版本号:

19043.1288

HBuilderX类型:

正式

HBuilderX版本号:

3.2.9

手机系统:

Android

手机系统版本号:

Android 10

手机厂商:

vivo

手机机型:

X50 Pro

页面类型:

vue

vue版本:

vue2

打包方式:

云端

项目创建方式:

HBuilderX

示例代码:

//当前接口请求数  
let requestNum = 0;  
//请求开始拦截器  
$http.requestStart = function(options) {  
    if (options.load) {  
        if (requestNum <= 0) {  
            //打开加载动画  
            uni.showLoading({  
                title: '加载中',  
                mask: true  
            });  
        }  
        requestNum += 1;  
    }  
    // 图片、视频上传大小限制  
    if (options.method == "FILE") {  
        // 文件最大字节: options.maxSize 可以在调用方法的时候加入参数  
        let maxSize = options.maxSize || '';  
        for (let item of options.files) {  
            if (item.fileType == 'image') {  
                if (maxSize && item.size > maxSize) {  
                    setTimeout(() => {  
                        uni.showToast({  
                            title: "图片过大,请重新上传",  
                            icon: "none"  
                        });  
                    }, 500);  
                    return false;  
                }  
            } else if (item.fileType == "video") {  
                if (item.duration < 3) {  
                    setTimeout(() => {  
                        uni.showToast({  
                            title: "视频长度不足3秒,请重新上传",  
                            icon: "none"  
                        });  
                    }, 500);  
                    return false;  
                }  
            }  
        }  
    }  
    //请求前加入token  
    try {  
        const token = uni.getStorageSync('Authorization') || '';  
        if (token) {  
            options.header['Authorization'] = token;  
            }  
    } catch (e) {}  

    return options; // return false 表示请求拦截,不会继续请求  
}  
//请求结束  
$http.requestEnd = function(options) {  
    //判断当前接口是否需要加载动画  
    if (options.load) {  
        requestNum = requestNum - 1;  
        if (requestNum <= 0) {  
            uni.hideLoading();  
        }  
    }  
}

操作步骤:

进入应用.点击home键进人后台运行 再次点击应用图标进入

预期结果:

loading 图标正常消失

实际结果:

loading 图标一直不消失

bug描述:

进入应用后,点击手机home 按键 后台运行,再次进入应用 loading 图标一直不消失


更多关于uni-app 手机点击home键程序后台运行 再次点击进入时 loading 图标显示不消失的实战教程也可以访问 https://www.itying.com/category-93-b0.html

1 回复

更多关于uni-app 手机点击home键程序后台运行 再次点击进入时 loading 图标显示不消失的实战教程也可以访问 https://www.itying.com/category-93-b0.html


这是一个典型的应用生命周期管理问题。当应用进入后台时,网络请求可能被挂起或中断,但你的请求计数器逻辑没有正确处理这种场景。

问题分析:

  1. 应用进入后台时,正在进行的网络请求可能被系统暂停
  2. 再次进入前台时,这些请求可能继续执行或失败,但requestNum计数器状态异常
  3. 由于requestNum没有归零,导致uni.hideLoading()无法被调用

解决方案:

在App.vue中添加应用生命周期监听:

export default {
  onLaunch() {
    // 监听应用进入前台
    uni.onAppShow(() => {
      // 重置请求计数器
      if (typeof $http !== 'undefined' && $http.requestNum > 0) {
        $http.requestNum = 0;
        uni.hideLoading();
      }
    });
    
    // 监听应用进入后台
    uni.onAppHide(() => {
      // 可以在这里处理后台状态
    });
  }
}

或者修改你的拦截器逻辑,增加超时自动隐藏:

// 当前接口请求数  
let requestNum = 0;
let loadingTimer = null;

// 请求开始拦截器
$http.requestStart = function(options) {
    if (options.load) {
        if (requestNum <= 0) {
            // 清除可能存在的定时器
            if (loadingTimer) clearTimeout(loadingTimer);
            
            // 打开加载动画
            uni.showLoading({
                title: '加载中',
                mask: true
            });
            
            // 设置超时自动隐藏(防止异常情况)
            loadingTimer = setTimeout(() => {
                if (requestNum > 0) {
                    requestNum = 0;
                    uni.hideLoading();
                }
            }, 30000); // 30秒超时
        }
        requestNum += 1;
    }
    // ... 其他代码
}

// 请求结束
$http.requestEnd = function(options) {
    if (options.load) {
        requestNum = requestNum - 1;
        if (requestNum <= 0) {
            if (loadingTimer) clearTimeout(loadingTimer);
            uni.hideLoading();
        }
    }
}
回到顶部