mobile v1.0.3:登录卡死定位增强(B-58)

- SDK 初始化与登录拆成两步分别超时,提示语区分卡在哪一步
- 登录失败时读取并展示 OpenIM SDK 日志文件结尾(去 ANSI 颜色码),用户拍照即可回传诊断信息
- 模拟器实测(Android 15 x86_64):initSDK+login 对 192.168.200.11 全流程正常,排除服务端与代码逻辑问题
- libgojni arm64 已验证 16KB 页对齐,排除新机型兼容性问题
This commit is contained in:
KIMI
2026-08-15 15:42:31 +08:00
parent e2cc59d8c1
commit a5b3a0e35f
3 changed files with 53 additions and 3 deletions
+16 -2
View File
@@ -80,7 +80,12 @@ class _LoginScreenState extends State<LoginScreen> {
password: password,
platformID: IMService.instance.platformID,
);
// 2. 登录 OpenIM SDK(服务器连不上时这一步可能长时间不返回,加超时兜底
// 2. 初始化消息组件(分两步超时,方便定位卡在哪一步
await IMService.instance.init().timeout(
const Duration(seconds: 15),
onTimeout: () => throw AuthException('消息组件初始化超时'),
);
// 3. 登录 OpenIM SDK
await IMService.instance.login(userID: result.userID, token: result.token).timeout(
const Duration(seconds: 20),
onTimeout: () => throw AuthException('连不上消息服务器,请确认手机连着公司内网 WiFi'),
@@ -102,7 +107,7 @@ class _LoginScreenState extends State<LoginScreen> {
}
}
/// 登录失败:在提示下方附上服务器自检结果,方便远程定位是哪一段不通
/// 登录失败:在提示下方附上服务器自检结果和 SDK 日志结尾,方便远程定位是哪一段不通
Future<void> _fail(String msg) async {
final parts = [msg];
try {
@@ -113,6 +118,15 @@ class _LoginScreenState extends State<LoginScreen> {
final sdkErr = IMService.instance.lastConnectError;
if (sdkErr != null && sdkErr.isNotEmpty) parts.add('消息组件报告:$sdkErr');
if (mounted) setState(() => _error = parts.join('\n'));
// SDK 日志可能较大,异步读完后再补一行提示用户拍照
try {
final tail = await IMService.instance.sdkLogTail();
if (tail.isNotEmpty && mounted) {
setState(() => _error = '${parts.join('\n')}\n—— SDK 日志结尾(拍照发给我)——\n$tail');
}
} catch (_) {
// 读日志失败不影响原提示
}
}
/// 逐个探测三个服务端口:能拿到任何 HTTP 响应就算通
+36
View File
@@ -39,6 +39,41 @@ class IMService extends ChangeNotifier {
/// 最近一次连接失败的原始错误(诊断展示用)
String? lastConnectError;
/// SDK 数据/日志目录(_doInit 时记录)
String? _dataDir;
/// 读 SDK 日志文件的结尾部分(定位「SDK 卡在哪」用)。读不到返回空串。
Future<String> sdkLogTail() async {
try {
final dataDir = _dataDir ?? '${(await getApplicationDocumentsDirectory()).path}/openim';
final dir = Directory(dataDir);
if (!dir.existsSync()) return '';
final files = dir
.listSync(recursive: true)
.whereType<File>()
.where((f) => f.path.endsWith('.log'))
.toList()
..sort((a, b) => b.lastModifiedSync().compareTo(a.lastModifiedSync()));
if (files.isEmpty) return '';
final file = files.first;
final len = file.lengthSync();
final start = len > 2048 ? len - 2048 : 0;
final raf = file.openSync();
try {
raf.setPositionSync(start);
final bytes = raf.readSync(len - start);
// 去掉日志里的 ANSI 颜色码,免得截图里出现乱码
return String.fromCharCodes(bytes)
.replaceAll(RegExp(r'\x1B\[[0-9;]*m'), '')
.trim();
} finally {
raf.closeSync();
}
} catch (_) {
return '';
}
}
/// 是否已登录
bool loggedIn = false;
@@ -98,6 +133,7 @@ class IMService extends ChangeNotifier {
Future<void> _doInit() async {
final dir = await getApplicationDocumentsDirectory();
final dataDir = '${dir.path}/openim';
_dataDir = dataDir;
await Directory(dataDir).create(recursive: true);
final ok = await OpenIM.iMManager.initSDK(
platformID: platformID,
+1 -1
View File
@@ -1,7 +1,7 @@
name: changlian
description: 畅联 —— 公司内部通讯 App(手机端)
publish_to: "none"
version: 1.0.2+3
version: 1.0.3+4
environment:
sdk: ">=3.6.0 <4.0.0"