V1.4.9: 修复启动被误判为"断网恢复"(并补齐 WebView 失效原因取证)

现场日志(1.4.8)显示启动瞬间就出现:
  20:46:59.636  NET-UP 设备网络已恢复, 重建歌曲源会话
  20:46:59.647  NET-REFRESH reason=net-up retried=0
  20:46:59.980  BOOT
即 NET-UP 出现在 BOOT 之前 —— 启动被当成了"断网后恢复"。

根因: KtvNetworkMonitor.start() 末尾无条件 onChange(initial),
注册 ConnectivityManager 回调时系统会回报一次初始状态,上层把它当成了状态跃迁。
而启动流程(onCreate)已经做过 startRemoteServer()/updateMobileQrOverlay()/
refreshLogDeviceContext()/DeviceMac 解析,所以这次"恢复"是纯粹重复劳动,且有副作用:
- SongApiClient.resetSourceSession() 白清掉刚建立的歌曲源会话;
- Eac19WindowGuard.noteUrlOk() 语义错误(还没取到任何地址就标记窗口正常,
  可能掩盖真正的歌曲源窗口到期提示);
- 状态栏被写成"网络已恢复"(启动瞬间就显示,用户可见的错误文案)。

修复:
- KtvNetworkMonitor.start/refresh 的回调签名改为 (online, initial),
  initial=true 表示"注册时的初始状态";
- MainActivity.onNetworkStateChanged(online, initial): 初始状态**只更新断网角标**,
  不做任何恢复动作;恢复动作(重建会话/重启点歌服务/刷新二维码/重试下载)
  只在真正的 offline→online 跃迁时执行。

同时补齐 WebView 失效原因的取证(旧日志只有"KtvApi 未导出"这一句,无法定因):
- wrapHtml 注入特性探测: 上报 WEBVIEW ua=... asyncFunction=yes|no promise=...
  (用 new Function 探测,避免探测语句自身引起语法错误)。Android 5.x 的 WebView
  可能是 Chrome 39~4x,不支持 async/await 会让**整个 ktv_api.js 语法报错** →
  window.KtvApi 未定义、桥永远不就绪,这条日志可直接确证;
- window.onerror 上报脚本解析/运行错误(JS-ERROR ... @line:col),语法错误也会触发;
- 合并重复的失败行: "JS-BRIDGE 初始化返回 false" 与
  "JS-BRIDGE 判定本机 WebView 不可用" 只保留后者(含原因)。

版本 1.4.8(28) 到 1.4.9(29);签名证书不变。ktv_api.js 未改动,KTV_BRIDGE_API 仍为 8。
This commit is contained in:
zijunchiang
2026-09-26 21:00:21 +08:00
parent 906fa210e4
commit b3b17210f1
6 changed files with 59 additions and 15 deletions
+20 -3
View File
@@ -388,11 +388,28 @@ class KtvJsBridge(context: Context) {
private fun wrapHtml(script: String): String {
val escaped = script.replace("</script", "<\\/script", ignoreCase = true)
// console.log 桥接:ktv_api.js 的 _log()/_log 细节(Try source / Token FAIL / do.php code=
// 等)原本只进 WebView 控制台,远程日志里完全看不到,点歌失败无从定位。
// 这里把它转发到 android.log → MiliLog,并保留原始 console 行为。
// 诊断 + console 桥(必须在主脚本之前执行):
// 1) 上报 WebView 内核版本与 ES2017(async/await) 支持情况 —— 老盒子(Android 5.x 的
// WebView 可能是 Chrome 39~4x)不支持 async/await 会让**整个脚本语法报错**,
// 表现为 `window.KtvApi` 未导出、桥永远不就绪;这条日志可直接定死该原因。
// (用 new Function 做特性探测,避免探测语句本身引起语法错误。)
// 2) window.onerror 捕获脚本解析/运行错误 —— 语法错误也会触发它,能拿到真实报错。
// 3) console.log 桥接:ktv_api.js 的 _log() 细节原本只进 WebView 控制台。
val consoleBridge = """
(function(){
try {
window.onerror = function(msg, src, line, col){
try { android.log('JS-ERROR ' + msg + ' @' + line + ':' + col); } catch(e) {}
};
} catch(e) {}
try {
var es = 'unknown';
try { new Function('return (async function(){})'); es = 'yes'; } catch(e) { es = 'no'; }
try {
android.log('WEBVIEW ua=' + navigator.userAgent +
' asyncFunction=' + es + ' promise=' + (typeof Promise));
} catch(e) {}
} catch(e) {}
try {
var orig = console.log;
console.log = function(){