242 lines
6.7 KiB
Markdown
Executable File
242 lines
6.7 KiB
Markdown
Executable File
# Android 应用启动时登录框不显示问题分析
|
||
|
||
## 🔍 问题描述
|
||
|
||
**现象**:Android 应用退出重新打开后,有时会出现无法加载所有功能的情况,具体表现为进入首页后没有显示下面的登录框,需要退出重进多次才能恢复正常。
|
||
|
||
## 📋 代码逻辑分析
|
||
|
||
### **1. 应用启动流程**
|
||
|
||
```dart
|
||
// main.dart -> splash -> main
|
||
main() -> KRAppRunData().kr_initializeUserInfo() -> Get.offAllNamed(Routes.KR_MAIN)
|
||
```
|
||
|
||
### **2. 登录状态初始化流程**
|
||
|
||
#### **A. 启动时初始化 (KRAppRunData.kr_initializeUserInfo)**
|
||
```dart
|
||
Future<void> kr_initializeUserInfo() async {
|
||
final String? userInfoString = await KRSecureStorage().kr_readData(key: _keyUserInfo);
|
||
|
||
if (userInfoString != null) {
|
||
// 解析用户信息
|
||
kr_token = userInfo['token'];
|
||
kr_account = userInfo['account'];
|
||
// ...
|
||
|
||
kr_isLogin.value = kr_token != null; // ⚠️ 关键:设置登录状态
|
||
if (kr_isLogin.value) {
|
||
await _iniUserInfo(); // 异步获取用户信息
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
#### **B. 首页控制器初始化 (KRHomeController._kr_initLoginStatus)**
|
||
```dart
|
||
void _kr_initLoginStatus() {
|
||
if (KRAppRunData().kr_isLogin.value) {
|
||
kr_currentViewStatus.value = KRHomeViewsStatus.kr_loggedIn;
|
||
kr_subscribeService.kr_refreshAll(); // ⚠️ 异步刷新订阅数据
|
||
} else {
|
||
kr_currentViewStatus.value = KRHomeViewsStatus.kr_notLoggedIn;
|
||
}
|
||
|
||
ever(KRAppRunData().kr_isLogin, (isLoggedIn) {
|
||
// 监听登录状态变化
|
||
});
|
||
}
|
||
```
|
||
|
||
### **3. 登录框显示逻辑**
|
||
|
||
#### **A. 首页视图判断 (KRHomeView.build)**
|
||
```dart
|
||
Widget build(BuildContext context) {
|
||
return Obx(() {
|
||
if (controller.kr_currentViewStatus.value == KRHomeViewsStatus.kr_notLoggedIn) {
|
||
return Scaffold(
|
||
body: Stack(
|
||
children: [
|
||
const KRHomeMapView(),
|
||
Positioned(
|
||
bottom: 0,
|
||
child: Container(
|
||
child: const KRLoginView(), // ⚠️ 登录框在这里显示
|
||
),
|
||
),
|
||
],
|
||
),
|
||
);
|
||
}
|
||
// 已登录状态的其他UI...
|
||
});
|
||
}
|
||
```
|
||
|
||
#### **B. 底部面板判断 (KRHomeBottomPanel._kr_buildDefaultView)**
|
||
```dart
|
||
Widget _kr_buildDefaultView(BuildContext context) {
|
||
final isNotLoggedIn = controller.kr_currentViewStatus.value == KRHomeViewsStatus.kr_notLoggedIn;
|
||
|
||
if (isNotLoggedIn) {
|
||
return SingleChildScrollView(
|
||
child: Column(
|
||
children: [
|
||
const KRHomeConnectionOptionsView(), // ⚠️ 登录选项在这里显示
|
||
],
|
||
),
|
||
);
|
||
}
|
||
// 已登录状态的其他内容...
|
||
}
|
||
```
|
||
|
||
## 🚨 问题根因分析
|
||
|
||
### **1. 竞态条件 (Race Condition)**
|
||
|
||
**问题**:`kr_initializeUserInfo()` 中的异步操作可能导致状态不一致
|
||
|
||
```dart
|
||
// 问题代码
|
||
kr_isLogin.value = kr_token != null; // 立即设置状态
|
||
if (kr_isLogin.value) {
|
||
await _iniUserInfo(); // 异步操作,可能失败
|
||
}
|
||
```
|
||
|
||
**风险**:
|
||
- 如果 `_iniUserInfo()` 失败,登录状态可能不正确
|
||
- 网络请求超时或失败时,状态可能不一致
|
||
|
||
### **2. 异步初始化时序问题**
|
||
|
||
**问题**:多个异步操作没有正确的依赖关系
|
||
|
||
```dart
|
||
// 启动流程
|
||
await KRAppRunData.getInstance().kr_initializeUserInfo(); // 异步1
|
||
Get.offAllNamed(Routes.KR_MAIN); // 立即跳转
|
||
|
||
// 首页初始化
|
||
_kr_initLoginStatus(); // 可能此时 kr_isLogin 还未正确设置
|
||
```
|
||
|
||
### **3. 状态监听器初始化时机**
|
||
|
||
**问题**:`ever()` 监听器可能在状态变化后才注册
|
||
|
||
```dart
|
||
// 可能的问题
|
||
kr_isLogin.value = true; // 状态已变化
|
||
ever(KRAppRunData().kr_isLogin, (isLoggedIn) { // 监听器注册太晚
|
||
// 这个回调可能不会立即触发
|
||
});
|
||
```
|
||
|
||
### **4. 订阅服务初始化失败**
|
||
|
||
**问题**:`kr_subscribeService.kr_refreshAll()` 可能失败
|
||
|
||
```dart
|
||
if (KRAppRunData().kr_isLogin.value) {
|
||
kr_currentViewStatus.value = KRHomeViewsStatus.kr_loggedIn;
|
||
kr_subscribeService.kr_refreshAll(); // 如果这个失败,UI状态可能不正确
|
||
}
|
||
```
|
||
|
||
## 🔧 潜在修复方案
|
||
|
||
### **1. 添加状态初始化延迟**
|
||
|
||
```dart
|
||
void _kr_initLoginStatus() {
|
||
// 延迟初始化,确保所有异步操作完成
|
||
Future.delayed(const Duration(milliseconds: 100), () {
|
||
if (KRAppRunData().kr_isLogin.value) {
|
||
kr_currentViewStatus.value = KRHomeViewsStatus.kr_loggedIn;
|
||
} else {
|
||
kr_currentViewStatus.value = KRHomeViewsStatus.kr_notLoggedIn;
|
||
}
|
||
});
|
||
}
|
||
```
|
||
|
||
### **2. 添加状态验证**
|
||
|
||
```dart
|
||
void _kr_initLoginStatus() {
|
||
// 验证登录状态的有效性
|
||
final isValidLogin = KRAppRunData().kr_token != null &&
|
||
KRAppRunData().kr_isLogin.value;
|
||
|
||
if (isValidLogin) {
|
||
kr_currentViewStatus.value = KRHomeViewsStatus.kr_loggedIn;
|
||
} else {
|
||
kr_currentViewStatus.value = KRHomeViewsStatus.kr_notLoggedIn;
|
||
}
|
||
}
|
||
```
|
||
|
||
### **3. 添加错误处理和重试机制**
|
||
|
||
```dart
|
||
void _kr_initLoginStatus() {
|
||
try {
|
||
if (KRAppRunData().kr_isLogin.value) {
|
||
kr_currentViewStatus.value = KRHomeViewsStatus.kr_loggedIn;
|
||
// 添加错误处理
|
||
kr_subscribeService.kr_refreshAll().catchError((error) {
|
||
KRLogUtil.kr_e('订阅服务初始化失败: $error', tag: 'HomeController');
|
||
// 重试或降级处理
|
||
});
|
||
} else {
|
||
kr_currentViewStatus.value = KRHomeViewsStatus.kr_notLoggedIn;
|
||
}
|
||
} catch (e) {
|
||
KRLogUtil.kr_e('登录状态初始化失败: $e', tag: 'HomeController');
|
||
kr_currentViewStatus.value = KRHomeViewsStatus.kr_notLoggedIn;
|
||
}
|
||
}
|
||
```
|
||
|
||
### **4. 添加状态同步检查**
|
||
|
||
```dart
|
||
void _kr_initLoginStatus() {
|
||
// 强制同步状态
|
||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||
final currentLoginStatus = KRAppRunData().kr_isLogin.value;
|
||
if (kr_currentViewStatus.value == KRHomeViewsStatus.kr_loggedIn && !currentLoginStatus) {
|
||
kr_currentViewStatus.value = KRHomeViewsStatus.kr_notLoggedIn;
|
||
} else if (kr_currentViewStatus.value == KRHomeViewsStatus.kr_notLoggedIn && currentLoginStatus) {
|
||
kr_currentViewStatus.value = KRHomeViewsStatus.kr_loggedIn;
|
||
}
|
||
});
|
||
}
|
||
```
|
||
|
||
## 📊 问题影响
|
||
|
||
1. **用户体验差**:需要多次重启应用才能正常使用
|
||
2. **功能不可用**:登录框不显示导致无法登录
|
||
3. **状态不一致**:UI状态与实际登录状态不匹配
|
||
|
||
## 🎯 建议修复优先级
|
||
|
||
1. **高优先级**:添加状态初始化延迟和验证
|
||
2. **中优先级**:添加错误处理和重试机制
|
||
3. **低优先级**:优化异步操作时序
|
||
|
||
## 📝 测试建议
|
||
|
||
1. **多次重启测试**:连续重启应用 10-20 次,观察登录框显示情况
|
||
2. **网络异常测试**:在网络不稳定环境下测试
|
||
3. **存储异常测试**:模拟存储读取失败的情况
|
||
4. **内存压力测试**:在低内存环境下测试
|
||
|
||
这个分析为后续的修复提供了明确的方向和具体的实现建议。
|