Android端Device.getInfo()加载缓慢,USB连接时恢复正常问题求助
根据你的技术栈和问题描述,结合提供的Capacitor web端Device.getInfo()代码,这个卡顿问题的核心原因大概率是**navigator.getBattery() API在Android Chrome非调试(未连USB)状态下的性能异常**。
问题分析
从你给出的web端实现代码可以看到,getInfo()方法会尝试调用navigator.getBattery()获取电池信息——虽然代码里加了try/catch捕获异常,但await navigator.getBattery()在Android Chrome未连接USB调试时,可能会因为浏览器的节流机制、底层硬件访问延迟等原因,导致这个Promise长时间处于pending状态,进而阻塞整个getInfo()方法的执行,表现为你看到的数分钟卡顿。而连接USB调试时,浏览器的调试模式会优化这类API的调用速度,所以能瞬间完成。
解决方案
你可以通过以下几种方式修复这个问题:
1. 给电池信息获取添加超时限制
修改Capacitor web端的getInfo()实现(或者在你的业务代码里封装一层),给navigator.getBattery()设置一个超时时间,超时后直接跳过电池信息的获取:
async getInfo(): Promise<DeviceInfo> { const ua = navigator.userAgent; const uaFields = this.parseUa(ua); let battery: any = {}; try { // 添加3秒超时,超时则放弃获取电池信息 const batteryPromise = navigator.getBattery(); const timeoutPromise = new Promise((_, reject) => setTimeout(() => reject('Timeout'), 3000)); battery = await Promise.race([batteryPromise, timeoutPromise]); } catch (e) { // 捕获超时或其他异常,直接使用默认空对象 battery = {}; } return Promise.resolve({ model: uaFields.model, platform: <'web'> 'web', appVersion: '', osVersion: uaFields.osVersion, manufacturer: navigator.vendor, isVirtual: false, batteryLevel: battery.level ?? null, isCharging: battery.charging ?? false, uuid: this.getUid() }); }
2. 完全跳过web端的电池信息获取
如果你的业务不需要电池相关数据,可以直接移除navigator.getBattery()的调用,彻底避免这个潜在的阻塞点:
async getInfo(): Promise<DeviceInfo> { const ua = navigator.userAgent; const uaFields = this.parseUa(ua); return Promise.resolve({ model: uaFields.model, platform: <'web'> 'web', appVersion: '', osVersion: uaFields.osVersion, manufacturer: navigator.vendor, isVirtual: false, batteryLevel: null, isCharging: false, uuid: this.getUid() }); }
3. 区分环境使用不同实现
在你的app-component中,判断当前是否是Android Chrome环境,手动处理Device.getInfo()的调用,比如在web环境下直接返回自定义的设备信息,绕过Capacitor的web插件:
import { Device } from '@capacitor/device'; async loadDeviceInfo() { let deviceInfo; const isAndroidChrome = /Android/.test(navigator.userAgent) && /Chrome/.test(navigator.userAgent); if (isAndroidChrome) { // 自定义web环境下的设备信息,跳过电池获取 const ua = navigator.userAgent; // 可复用Capacitor的parseUa逻辑,或自己简单解析UA字段 deviceInfo = { model: '', platform: 'web', appVersion: '', osVersion: '', manufacturer: navigator.vendor, isVirtual: false, batteryLevel: null, isCharging: false, uuid: '' }; } else { // 正常调用Device.getInfo() deviceInfo = await Device.getInfo(); } // 后续处理设备信息逻辑 }
验证建议
修改后,在Android手机上断开USB,直接通过Chrome访问你的应用,确认Device.getInfo()的调用是否恢复正常速度。
内容的提问来源于stack exchange,提问作者roma88RM

