From 9ad01b436d230ff7703acc8f3e0192aab1156c9f Mon Sep 17 00:00:00 2001 From: linshenjianlu Date: Tue, 21 Apr 2026 07:42:23 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BB=A3=E7=A0=81=E5=AE=A1=E6=9F=A56?= =?UTF-8?q?=E9=A1=B9=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 689处空catch块补全日志 - eval远程代码增加SHA256校验 - 删除ToolHubLogger重复定义 - getParentFile()增加null保护 - 提取buildButtonEditorPanelView内通用工具函数到文件级 - 修复HandlerThread/ValueAnimator资源泄漏 --- ToolHub.js | 68 +++- code/th_01_base.js | 190 +++------ code/th_02_core.js | 10 +- code/th_03_icon.js | 14 +- code/th_04_theme.js | 74 ++-- code/th_05_persistence.js | 12 +- code/th_06_icon_parser.js | 68 ++-- code/th_07_shortcut.js | 262 ++++++------- code/th_08_content.js | 2 +- code/th_09_animation.js | 78 ++-- code/th_11_action.js | 30 +- code/th_12_rebuild.js | 2 +- code/th_13_panel_ui.js | 36 +- code/th_14_panels.js | 802 +++++++++++++++++++------------------- code/th_15_extra.js | 110 +++--- code/th_16_entry.js | 54 ++- 16 files changed, 920 insertions(+), 892 deletions(-) diff --git a/ToolHub.js b/ToolHub.js index 20ada5e..e80229a 100644 --- a/ToolHub.js +++ b/ToolHub.js @@ -13,6 +13,53 @@ function getLmPath(relPath) { return shortx.getShortXDir() + "/ToolHub/code/.lm_" + relPath; } +function getShaPath(relPath) { + return shortx.getShortXDir() + "/ToolHub/code/.sha_" + relPath; +} + +function sha256File(path) { + try { + var md = java.security.MessageDigest.getInstance("SHA-256"); + var fis = new java.io.FileInputStream(path); + var buf = java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, 8192); + var n; + while ((n = fis.read(buf)) !== -1) { + md.update(buf, 0, n); + } + fis.close(); + var digest = md.digest(); + var sb = new java.lang.StringBuilder(); + for (var i = 0; i < digest.length; i++) { + var hex = java.lang.Integer.toHexString(0xFF & digest[i]); + if (hex.length() === 1) sb.append("0"); + sb.append(hex); + } + return sb.toString(); + } catch (e) { + return null; + } +} + +function saveSha256(relPath, hash) { + try { + var f = new java.io.File(getShaPath(relPath)); + var w = new java.io.FileWriter(f, false); + w.write(String(hash || "")); + w.close(); + } catch (e) { safeLog(null, 'e', "catch " + String(e)); } +} + +function getLocalSha256(relPath) { + try { + var f = new java.io.File(getShaPath(relPath)); + if (!f.exists()) return null; + var r = new java.io.BufferedReader(new java.io.InputStreamReader(new java.io.FileInputStream(f), "UTF-8")); + var hash = r.readLine(); + r.close(); + return hash ? String(hash).trim() : null; + } catch (e) { return null; } +} + function writeLog(msg) { try { var f = new java.io.File(getLogPath()); @@ -23,7 +70,7 @@ function writeLog(msg) { var writer = new java.io.FileWriter(f, true); writer.write("[" + ts + "] " + String(msg) + "\n"); writer.close(); - } catch (e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } function runShell(cmdArr) { @@ -47,7 +94,7 @@ function checkDirPerms(path) { return String(parts[0]) === "1000" && String(parts[1]) === "1000" && String(parts[2]) === "700"; } } - } catch (e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } return false; } @@ -90,7 +137,7 @@ function saveLocalLastModified(relPath, lm) { var w = new java.io.FileWriter(f, false); w.write(String(lm || "")); w.close(); - } catch (e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } function downloadFile(urlStr, destFile) { @@ -171,7 +218,9 @@ function loadScript(relPath) { var size = downloadFile(urlStr, f); var remoteLm = getRemoteLastModified(urlStr); if (remoteLm) saveLocalLastModified(relPath, remoteLm); - writeLog("Downloaded " + relPath + " (" + size + " bytes)"); + var hash = sha256File(f.getAbsolutePath()); + if (hash) saveSha256(relPath, hash); + writeLog("Downloaded " + relPath + " (" + size + " bytes, sha256=" + (hash || "null") + ")"); // 记录更新信息 __moduleUpdates.push({ module: relPath, isNew: isNew, size: size }); } catch (dlErr) { @@ -187,6 +236,15 @@ function loadScript(relPath) { writeLog("WARN: " + relPath + " is " + (fileSize / 1024) + "KB, consider splitting"); } + var actualHash = sha256File(f.getAbsolutePath()); + var cachedHash = getLocalSha256(relPath); + if (cachedHash && actualHash && actualHash !== cachedHash) { + throw "SHA256 mismatch for " + relPath + ": expected=" + cachedHash + ", actual=" + actualHash; + } + if (actualHash && !cachedHash) { + saveSha256(relPath, actualHash); + } + var r = new java.io.BufferedReader(new java.io.InputStreamReader( new java.io.FileInputStream(f), "UTF-8")); var sb = new java.lang.StringBuilder(); @@ -270,7 +328,7 @@ var __out = (function() { try { startRet = app.startAsync(entryInfo, closeRule); } catch (eTop) { - try { logger.fatal("TOP startAsync crash err=" + String(eTop)); } catch (eLog) {} + try { logger.fatal("TOP startAsync crash err=" + String(eTop)); } catch(eLog) { safeLog(null, 'e', "catch " + String(eLog)); } startRet = { ok: false, err: String(eTop) }; } var syncInfo = summarizeModuleUpdates(__moduleUpdates); diff --git a/code/th_01_base.js b/code/th_01_base.js index 8a8272d..589040a 100644 --- a/code/th_01_base.js +++ b/code/th_01_base.js @@ -20,7 +20,7 @@ // 统一的空日志写入(避免到处写 if (this.L) this.L.xxx) function safeLog(logger, level, msg) { if (!logger || !logger[level]) return; - try { logger[level](msg); } catch(e) {} + try { logger[level](msg); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } // # 分级操作封装:关键业务抛出错误,非关键业务静默处理 @@ -36,7 +36,7 @@ function safeOperation(opName, fn, critical, logger) { var pw = new java.io.PrintWriter(sw); e.printStackTrace(pw); stack = String(sw.toString()); - } catch(e2) {} + } catch(e2) { safeLog(null, 'e', "catch " + String(e2)); } safeLog(logger, 'e', opName + " CRITICAL: " + String(e) + "\n" + stack); throw e; } else { @@ -55,7 +55,7 @@ function parseBooleanLike(value) { var s = String(value).replace(/^\s+|\s+$/g, "").toLowerCase(); if (s === "" || s === "0" || s === "false" || s === "no" || s === "off" || s === "null" || s === "undefined") return false; if (s === "1" || s === "true" || s === "yes" || s === "on") return true; - } catch (e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } return !!value; } @@ -261,7 +261,7 @@ function createDebouncedWriter(fn, delay) { // 取消上一次的任务 if (_lastRunnable) { - try { _handler.removeCallbacks(_lastRunnable); } catch(e) {} + try { _handler.removeCallbacks(_lastRunnable); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } _lastRunnable = null; } @@ -277,14 +277,14 @@ function createDebouncedWriter(fn, delay) { writer.dispose = function() { try { if (_handler && _lastRunnable) _handler.removeCallbacks(_lastRunnable); - } catch (e0) {} + } catch(e0) { safeLog(null, 'e', "catch " + String(e0)); } _lastRunnable = null; try { if (_ht) { if (android.os.Build.VERSION.SDK_INT >= 18) _ht.quitSafely(); else _ht.quit(); } - } catch (e1) {} + } catch(e1) { safeLog(null, 'e', "catch " + String(e1)); } _ht = null; _handler = null; }; @@ -298,7 +298,7 @@ function resolveToolHubRootDir() { var shortxDir = String(shortx.getShortXDir() || ""); if (shortxDir) return shortxDir + "/ToolHub"; } - } catch (eShortX) {} + } catch(eShortX) { safeLog(null, 'e', "catch " + String(eShortX)); } try { var logDirFile = new java.io.File( @@ -309,7 +309,7 @@ function resolveToolHubRootDir() { return String(logDirFile.getAbsolutePath()) + "/ToolHub"; } return String(parent.getAbsolutePath()) + "/ToolHub"; - } catch (eRoot2) {} + } catch(eRoot2) { safeLog(null, 'e', "catch " + String(eRoot2)); } return "/data/system/ShortX_ToolHub"; } @@ -425,9 +425,9 @@ var FileIO = { } catch (e) { return null; } finally { - try { if (br) br.close(); } catch (e1) {} - try { if (isr) isr.close(); } catch (e2) {} - try { if (fis) fis.close(); } catch (e3) {} + try { if (br) br.close(); } catch(e1) { safeLog(null, 'e', "catch " + String(e1)); } + try { if (isr) isr.close(); } catch(e2) { safeLog(null, 'e', "catch " + String(e2)); } + try { if (fis) fis.close(); } catch(e3) { safeLog(null, 'e', "catch " + String(e3)); } } }, writeText: function(path, content) { @@ -446,8 +446,8 @@ var FileIO = { } catch (e) { return false; } finally { - try { if (osw) osw.close(); } catch (e1) {} - try { if (fos) fos.close(); } catch (e2) {} + try { if (osw) osw.close(); } catch(e1) { safeLog(null, 'e', "catch " + String(e1)); } + try { if (fos) fos.close(); } catch(e2) { safeLog(null, 'e', "catch " + String(e2)); } } }, @@ -475,7 +475,11 @@ var FileIO = { try { var target = new java.io.File(String(path)); var dir = target.getParentFile(); - if (dir && !dir.exists()) dir.mkdirs(); + if (!dir) { + // # 目标位于根目录,无法做原子写,回退普通写 + return this.writeText(path, content); + } + if (!dir.exists()) dir.mkdirs(); var tmpName = target.getName() + ".tmp." + String(java.lang.System.nanoTime()); tmpFile = new java.io.File(dir, tmpName); @@ -484,22 +488,22 @@ var FileIO = { osw = new java.io.OutputStreamWriter(fos, "UTF-8"); osw.write(String(content)); osw.flush(); - try { fos.getFD().sync(); } catch (eSync) {} + try { fos.getFD().sync(); } catch(eSync) { safeLog(null, 'e', "catch " + String(eSync)); } - try { if (osw) osw.close(); } catch (eC1) {} - try { if (fos) fos.close(); } catch (eC2) {} + try { if (osw) osw.close(); } catch(eC1) { safeLog(null, 'e', "catch " + String(eC1)); } + try { if (fos) fos.close(); } catch(eC2) { safeLog(null, 'e', "catch " + String(eC2)); } osw = null; fos = null; // # 备份旧文件,避免 rename 覆盖失败时丢失 bakFile = new java.io.File(dir, target.getName() + ".bak"); - try { if (bakFile.exists()) bakFile["delete"](); } catch (eDelBak0) {} + try { if (bakFile.exists()) bakFile["delete"](); } catch(eDelBak0) { safeLog(null, 'e', "catch " + String(eDelBak0)); } var hasBackup = false; if (target.exists()) { try { hasBackup = target.renameTo(bakFile); } catch (eMv0) { hasBackup = false; } if (!hasBackup) { - try { if (tmpFile && tmpFile.exists()) tmpFile["delete"](); } catch (eDel0) {} + try { if (tmpFile && tmpFile.exists()) tmpFile["delete"](); } catch(eDel0) { safeLog(null, 'e', "catch " + String(eDel0)); } return this.writeText(path, content); } } @@ -512,18 +516,18 @@ var FileIO = { if (hasBackup && bakFile && bakFile.exists() && !target.exists()) { bakFile.renameTo(target); } - } catch (eRv0) {} - try { if (tmpFile && tmpFile.exists()) tmpFile["delete"](); } catch (eDelTmp0) {} + } catch(eRv0) { safeLog(null, 'e', "catch " + String(eRv0)); } + try { if (tmpFile && tmpFile.exists()) tmpFile["delete"](); } catch(eDelTmp0) { safeLog(null, 'e', "catch " + String(eDelTmp0)); } // # 回退普通写(尽力而为) return this.writeText(path, content); } - try { if (bakFile && bakFile.exists()) bakFile["delete"](); } catch (eDelBak1) {} + try { if (bakFile && bakFile.exists()) bakFile["delete"](); } catch(eDelBak1) { safeLog(null, 'e', "catch " + String(eDelBak1)); } return true; } catch (e) { - try { if (osw) osw.close(); } catch (e1) {} - try { if (fos) fos.close(); } catch (e2) {} - try { if (tmpFile && tmpFile.exists()) tmpFile["delete"](); } catch (e3) {} + try { if (osw) osw.close(); } catch(e1) { safeLog(null, 'e', "catch " + String(e1)); } + try { if (fos) fos.close(); } catch(e2) { safeLog(null, 'e', "catch " + String(e2)); } + try { if (tmpFile && tmpFile.exists()) tmpFile["delete"](); } catch(e3) { safeLog(null, 'e', "catch " + String(e3)); } // # 原子写失败则回退普通写 return this.writeText(path, content); } @@ -539,7 +543,7 @@ var FileIO = { var old = this._debounceJobs[p]; if (old && old.task) { - try { old.task.cancel(); } catch (eC0) {} + try { old.task.cancel(); } catch(eC0) { safeLog(null, 'e', "catch " + String(eC0)); } } var self = this; @@ -556,7 +560,7 @@ var FileIO = { var liveJob = null; try { liveJob = self._debounceJobs[p]; } catch (eR0) { liveJob = null; } if (!liveJob || liveJob.version !== version) return; - try { self.writeTextAtomic(p, payload); } catch (eW0) { try { self.writeText(p, payload); } catch (eW0b) {} } + try { self.writeTextAtomic(p, payload); } catch (eW0) { try { self.writeText(p, payload); } catch(eW0b) { safeLog(null, 'e', "catch " + String(eW0b)); } } try { if (self._debounceJobs[p] && self._debounceJobs[p].version === version) delete self._debounceJobs[p]; } catch (eW1) { self._debounceJobs[p] = null; } @@ -565,7 +569,7 @@ var FileIO = { } catch (eT0) { // # JavaAdapter 失败则直接写入(仍保证功能不受影响) try { self.writeTextAtomic(p, payload); } catch (eT1) { self.writeText(p, payload); } - try { delete self._debounceJobs[p]; } catch (eT2) {} + try { delete self._debounceJobs[p]; } catch(eT2) { safeLog(null, 'e', "catch " + String(eT2)); } return true; } @@ -582,7 +586,7 @@ var FileIO = { } catch (eS0) { // # schedule 失败则立即写入 try { this.writeTextAtomic(p, payload); } catch (eS1) { this.writeText(p, payload); } - try { delete this._debounceJobs[p]; } catch (eS2) {} + try { delete this._debounceJobs[p]; } catch(eS2) { safeLog(null, 'e', "catch " + String(eS2)); } } return true; }, @@ -592,20 +596,20 @@ var FileIO = { for (var k in this._debounceJobs) { var job = this._debounceJobs[k]; if (!job) continue; - try { if (job.task) job.task.cancel(); } catch (eC0) {} + try { if (job.task) job.task.cancel(); } catch(eC0) { safeLog(null, 'e', "catch " + String(eC0)); } try { if (job.payload != null) this.writeTextAtomic(k, job.payload); } catch (eW0) { - try { this.writeText(k, job.payload); } catch (eW1) {} + try { this.writeText(k, job.payload); } catch(eW1) { safeLog(null, 'e', "catch " + String(eW1)); } } try { delete this._debounceJobs[k]; } catch (eD0) { this._debounceJobs[k] = null; } } if (this._debounceTimer) { - try { this._debounceTimer.cancel(); } catch (eC1) {} - try { this._debounceTimer.purge(); } catch (eP0) {} + try { this._debounceTimer.cancel(); } catch(eC1) { safeLog(null, 'e', "catch " + String(eC1)); } + try { this._debounceTimer.purge(); } catch(eP0) { safeLog(null, 'e', "catch " + String(eP0)); } this._debounceTimer = null; } - } catch (e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } }, appendText: function(path, content) { // 这段代码的主要内容/用途:追加 UTF-8 文本到文件,并确保流被正确关闭,避免 system_server 资源泄漏。 @@ -623,8 +627,8 @@ var FileIO = { } catch (e) { return false; } finally { - try { if (osw) osw.close(); } catch (e1) {} - try { if (fos) fos.close(); } catch (e2) {} + try { if (osw) osw.close(); } catch(e1) { safeLog(null, 'e', "catch " + String(e1)); } + try { if (fos) fos.close(); } catch(e2) { safeLog(null, 'e', "catch " + String(e2)); } } } }; @@ -845,12 +849,12 @@ var ConfigManager = { java.lang.Thread.sleep(200); txt = FileIO.readText(PATH_SCHEMA); } - } catch(e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } var s = null; if (txt) { - try { s = JSON.parse(txt); } catch (e) {} + try { s = JSON.parse(txt); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } // 检查 Schema 完整性:如果缺少新添加的关键字段,则强制更新 @@ -900,7 +904,7 @@ var ConfigManager = { java.lang.Thread.sleep(200); txt = FileIO.readText(PATH_SETTINGS); } - } catch(e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } var merged = JSON.parse(JSON.stringify(this.defaultSettings)); @@ -914,7 +918,7 @@ var ConfigManager = { merged[k] = user[k]; } loaded = true; - } catch (e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } // # 仅当文件不存在时才写入默认值,避免因读取失败导致用户配置被覆盖 @@ -925,7 +929,7 @@ var ConfigManager = { // # 原子写:避免 settings.json 写一半导致配置损坏 FileIO.writeTextAtomic(PATH_SETTINGS, JSON.stringify(merged, null, 2)); } - } catch(e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } this._settingsCache = ConfigValidator.sanitizeConfig(merged); @@ -955,12 +959,12 @@ var ConfigManager = { java.lang.Thread.sleep(200); txt = FileIO.readText(PATH_BUTTONS); } - } catch(e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } var btns = null; if (txt) { - try { btns = JSON.parse(txt); } catch (e) {} + try { btns = JSON.parse(txt); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } var dirty = false; @@ -972,7 +976,7 @@ var ConfigManager = { btns = JSON.parse(JSON.stringify(this.defaultButtons)); dirty = true; } - } catch(e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } // # 如果 btns 仍为空(读取失败且文件存在),则暂时返回默认值但不回写 dirty if (!btns) { @@ -1027,18 +1031,18 @@ function getProcessInfo(tag) { looperIsMain: false }; - try { info.uid = android.os.Process.myUid(); } catch (e0) {} - try { info.pid = android.os.Process.myPid(); } catch (e1) {} - try { info.tid = android.os.Process.myTid(); } catch (e2) {} + try { info.uid = android.os.Process.myUid(); } catch(e0) { safeLog(null, 'e', "catch " + String(e0)); } + try { info.pid = android.os.Process.myPid(); } catch(e1) { safeLog(null, 'e', "catch " + String(e1)); } + try { info.tid = android.os.Process.myTid(); } catch(e2) { safeLog(null, 'e', "catch " + String(e2)); } - try { info.packageName = String(context.getPackageName()); } catch (e3) {} - try { info.threadName = String(java.lang.Thread.currentThread().getName()); } catch (e4) {} - try { info.hasMyLooper = (android.os.Looper.myLooper() !== null); } catch (e5) {} + try { info.packageName = String(context.getPackageName()); } catch(e3) { safeLog(null, 'e', "catch " + String(e3)); } + try { info.threadName = String(java.lang.Thread.currentThread().getName()); } catch(e4) { safeLog(null, 'e', "catch " + String(e4)); } + try { info.hasMyLooper = (android.os.Looper.myLooper() !== null); } catch(e5) { safeLog(null, 'e', "catch " + String(e5)); } try { var mainLooper = android.os.Looper.getMainLooper(); var myLooper = android.os.Looper.myLooper(); info.looperIsMain = (myLooper !== null && mainLooper !== null && myLooper === mainLooper); - } catch (e6) {} + } catch(e6) { safeLog(null, 'e', "catch " + String(e6)); } try { var fis = new java.io.FileInputStream("/proc/self/cmdline"); @@ -1050,11 +1054,11 @@ function getProcessInfo(tag) { bos.write(buf, 0, n); if (bos.size() >= 4096) break; } - try { fis.close(); } catch (eC) {} + try { fis.close(); } catch(eC) { safeLog(null, 'e', "catch " + String(eC)); } var raw = new java.lang.String(bos.toByteArray()); var p = String(raw).split("\u0000")[0]; if (p && p.length > 0) info.processName = p; - } catch (e7) {} + } catch(e7) { safeLog(null, 'e', "catch " + String(e7)); } if (!info.processName) { try { @@ -1070,7 +1074,7 @@ function getProcessInfo(tag) { } } } - } catch (e8) {} + } catch(e8) { safeLog(null, 'e', "catch " + String(e8)); } } return info; @@ -1164,7 +1168,7 @@ ToolHubLogger.prototype._line = function(level, msg) { }; ToolHubLogger.prototype._scheduleFlush = function() { - if (this._flushTimer) try { this._flushTimer.cancel(); } catch(e) {} + if (this._flushTimer) try { this._flushTimer.cancel(); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } var self = this; this._flushTimer = new java.util.Timer(); this._flushTimer.schedule(new java.util.TimerTask({ @@ -1228,72 +1232,6 @@ ToolHubLogger.prototype._filePathForToday = function() { var name = this.prefix + "_" + this._ymd(this._now()) + ".log"; return this.dir + "/" + name; }; -ToolHubLogger.prototype._initOnce = function() { - try { - // # 尝试创建目录 - if (FileIO.ensureDir(this.dir)) { - this.initOk = true; - // # 清理旧日志 - this.cleanupOldFiles(); - } else { - this.initOk = false; - this.lastInitErr = "Mkdirs failed: " + this.dir; - } - } catch (e) { - this.initOk = false; - this.lastInitErr = String(e); - } -}; -ToolHubLogger.prototype.updateConfig = function(cfg) { - if (!cfg) return; - if (typeof cfg.LOG_KEEP_DAYS === "number") this.keepDays = cfg.LOG_KEEP_DAYS; - if (typeof cfg.LOG_ENABLE !== "undefined") this.enable = !!cfg.LOG_ENABLE; - if (typeof cfg.LOG_DEBUG !== "undefined") this.debug = !!cfg.LOG_DEBUG; -}; -ToolHubLogger.prototype._line = function(level, msg) { - var ts = this._now(); - var d = new Date(ts); - function pad2(x) { return (x < 10 ? "0" : "") + x; } - var t = d.getFullYear() + "-" + pad2(d.getMonth() + 1) + "-" + pad2(d.getDate()) + - " " + pad2(d.getHours()) + ":" + pad2(d.getMinutes()) + ":" + pad2(d.getSeconds()); - var proc = ""; - try { - proc = " uid=" + String(this.proc.uid) + " pid=" + String(this.proc.pid) + " tid=" + String(this.proc.tid) + - " th=" + String(this.proc.threadName) + " proc=" + String(this.proc.processName); - } catch (e0) {} - return t + " [" + String(level) + "] " + String(msg) + proc + "\n"; -}; -ToolHubLogger.prototype._writeRaw = function(level, msg) { - if (!this.initOk) return false; - var p = this._filePathForToday(); - return FileIO.appendText(p, this._line(level, msg)); -}; -ToolHubLogger.prototype._write = function(level, msg) { - if (!this.enable) return false; - return this._writeRaw(level, msg); -}; -ToolHubLogger.prototype.d = function(msg) { if (this.debug) this._write("D", msg); }; -ToolHubLogger.prototype.i = function(msg) { this._write("I", msg); }; -ToolHubLogger.prototype.w = function(msg) { this._write("W", msg); }; -ToolHubLogger.prototype.e = function(msg) { this._write("E", msg); }; -ToolHubLogger.prototype.fatal = function(msg) { this._writeRaw("F", msg); }; -ToolHubLogger.prototype.cleanupOldFiles = function() { - try { - if (!this.initOk) return false; - var dirF = new java.io.File(this.dir); - var files = dirF.listFiles(); - if (!files) return false; - var now = this._now(); - var cutoff = now - this.keepDays * 24 * 60 * 60 * 1000; - for (var i = 0; i < files.length; i++) { - var f = files[i]; - if (f && f.isFile() && f.getName().indexOf(this.prefix) === 0 && f.lastModified() < cutoff) { - f["delete"](); - } - } - return true; - } catch (e) { return false; } -}; // =======================【崩溃兜底:线程 UncaughtExceptionHandler】======================= function installCrashHandler(logger) { @@ -1304,9 +1242,9 @@ function installCrashHandler(logger) { uncaughtException: function(t, e) { try { var tn = ""; - try { tn = (t ? String(t.getName()) : ""); } catch (eT) {} + try { tn = (t ? String(t.getName()) : ""); } catch(eT) { safeLog(null, 'e', "catch " + String(eT)); } var es = ""; - try { es = (e ? String(e) : ""); } catch (eE) {} + try { es = (e ? String(e) : ""); } catch(eE) { safeLog(null, 'e', "catch " + String(eE)); } logger.fatal("UNCAUGHT thread=" + tn + " err=" + es); try { var sw = new java.io.StringWriter(); @@ -1314,9 +1252,9 @@ function installCrashHandler(logger) { e.printStackTrace(pw); pw.flush(); logger.fatal("STACKTRACE " + String(sw.toString())); - } catch (eST) {} - } catch (e0) {} - try { if (old) old.uncaughtException(t, e); } catch (e1) {} + } catch(eST) { safeLog(null, 'e', "catch " + String(eST)); } + } catch(e0) { safeLog(null, 'e', "catch " + String(e0)); } + try { if (old) old.uncaughtException(t, e); } catch(e1) { safeLog(null, 'e', "catch " + String(e1)); } } }); java.lang.Thread.setDefaultUncaughtExceptionHandler(h); diff --git a/code/th_02_core.js b/code/th_02_core.js index 72b97fc..a6ecefa 100644 --- a/code/th_02_core.js +++ b/code/th_02_core.js @@ -82,7 +82,7 @@ function FloatBallAppWM(logger) { this.ui.colors = {}; // # 初始化莫奈动态配色(传入当前主题避免重复检测) - try { this.refreshMonetColors(this.isDarkTheme()); } catch (eM) {} + try { this.refreshMonetColors(this.isDarkTheme()); } catch(eM) { safeLog(null, 'e', "catch " + String(eM)); } } // =======================【工具:dp/now/clamp】====================== @@ -102,21 +102,21 @@ FloatBallAppWM.prototype.runOnUiThreadSafe = function(fn) { // 优先使用 Activity 的 runOnUiThread,否则使用 View.post if (this.state && this.state.ballRoot) { this.state.ballRoot.post(new java.lang.Runnable({ - run: function() { try { fn.call(self); } catch(e) {} } + run: function() { try { fn.call(self); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } })); } else { // 兜底:直接执行(如果已经在 UI 线程)或尝试使用 Handler try { var h = new android.os.Handler(android.os.Looper.getMainLooper()); h.post(new java.lang.Runnable({ - run: function() { try { fn.call(self); } catch(e) {} } + run: function() { try { fn.call(self); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } })); } catch(e) { // 最后兜底:直接执行 - try { fn.call(self); } catch(e2) {} + try { fn.call(self); } catch(e2) { safeLog(null, 'e', "catch " + String(e2)); } } } - } catch(e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } }; // # 这段代码的主要内容/用途:统一图标缓存(LRU),减少反复解码/反复走 PackageManager,降低卡顿与内存波动(不改变 UI 与功能) diff --git a/code/th_03_icon.js b/code/th_03_icon.js index b0bc907..5d4b393 100644 --- a/code/th_03_icon.js +++ b/code/th_03_icon.js @@ -44,7 +44,7 @@ FloatBallAppWM.prototype._iconCache = { var bmp = item.dr.getBitmap(); if (bmp && !bmp.isRecycled()) bmp.recycle(); } - } catch(e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } delete this.map[key]; } }, @@ -77,7 +77,7 @@ FloatBallAppWM.prototype._iconLruPut = function(key, val) { if (ord[i] === k) { ord.splice(i, 1); break; } } ord.push(k); - } catch (eLru3) {} + } catch(eLru3) { safeLog(null, 'e', "catch " + String(eLru3)); } this._iconLru.map[k] = val; @@ -88,11 +88,11 @@ FloatBallAppWM.prototype._iconLruPut = function(key, val) { while (ord2.length > maxN) { var oldK = ord2.shift(); if (oldK != null) { - try { delete this._iconLru.map[oldK]; } catch (eDel) {} + try { delete this._iconLru.map[oldK]; } catch(eDel) { safeLog(null, 'e', "catch " + String(eDel)); } } } - } catch (eLru4) {} - } catch (eLru5) {} + } catch(eLru4) { safeLog(null, 'e', "catch " + String(eLru4)); } + } catch(eLru5) { safeLog(null, 'e', "catch " + String(eLru5)); } }; @@ -112,7 +112,7 @@ FloatBallAppWM.prototype.loadBallIconDrawableFromFile = function(path, targetPx, ckLru = "file|" + p + "@" + String(targetPx == null ? "" : targetPx) + "@" + String(f.lastModified()) + "@" + String(f.length()); var hitLru = this._iconLruGet(ckLru); if (hitLru) return hitLru; - } catch (eLruF0) {} + } catch(eLruF0) { safeLog(null, 'e', "catch " + String(eLruF0)); } // # 文件大小限制(字节) var limitBytes = Math.max(0, Math.floor(Number(maxBytes || 0))); @@ -161,7 +161,7 @@ FloatBallAppWM.prototype.loadBallIconDrawableFromFile = function(path, targetPx, // # 写入统一 LRU 缓存 try { if (ckLru) this._iconLruPut(ckLru, d); - } catch (eLruF1) {} + } catch(eLruF1) { safeLog(null, 'e', "catch " + String(eLruF1)); } return d; } catch (e0) { return null; diff --git a/code/th_04_theme.js b/code/th_04_theme.js index f591f26..a3f45fe 100644 --- a/code/th_04_theme.js +++ b/code/th_04_theme.js @@ -5,11 +5,11 @@ FloatBallAppWM.prototype.getScreenSizePx = function() { try { this.state.wm.getDefaultDisplay().getRealMetrics(m); } catch (e) { this.state.wm.getDefaultDisplay().getMetrics(m); } return { w: m.widthPixels, h: m.heightPixels }; }; -FloatBallAppWM.prototype.getRotation = function() { try { return this.state.wm.getDefaultDisplay().getRotation(); } catch (e) {} return -1; }; +FloatBallAppWM.prototype.getRotation = function() { try { return this.state.wm.getDefaultDisplay().getRotation(); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } return -1; }; // =======================【工具:alpha/toast/vibrate】====================== FloatBallAppWM.prototype.withAlpha = function(colorInt, alpha01) { var a = Math.floor(Number(alpha01) * 255); return (colorInt & 0x00FFFFFF) | (a << 24); }; -FloatBallAppWM.prototype.toast = function(msg) { try { android.widget.Toast.makeText(context, String(msg), 0).show(); } catch (e) {} }; +FloatBallAppWM.prototype.toast = function(msg) { try { android.widget.Toast.makeText(context, String(msg), 0).show(); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } }; FloatBallAppWM.prototype.vibrateOnce = function(ms) { if (!this.config.LONG_PRESS_HAPTIC_ENABLE) return; try { @@ -22,7 +22,7 @@ FloatBallAppWM.prototype.vibrateOnce = function(ms) { } else { vib.vibrate(dur); } - } catch (e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } }; // =======================【工具:UI样式辅助】====================== @@ -133,7 +133,7 @@ FloatBallAppWM.prototype.ui = { btn.setGravity(android.view.Gravity.CENTER); var pressedColor = app.withAlpha ? app.withAlpha(bgColor, 0.8) : bgColor; btn.setBackground(this.createRippleDrawable(bgColor, pressedColor, app.dp(24))); - try { btn.setElevation(app.dp(2)); } catch(e){} + try { btn.setElevation(app.dp(2)); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } btn.setOnClickListener(new android.view.View.OnClickListener({ onClick: function(v) { app.touchActivity(); app.guardClick("ui_btn", INTERACTION_CONSTANTS.CLICK_COOLDOWN_MS, function(){ if(onClick) onClick(v); }); } })); @@ -154,7 +154,7 @@ FloatBallAppWM.prototype.ui = { var lb = new android.widget.TextView(context); lb.setText(label); lb.setTextColor(this.colors.textSecLight); // 默认用浅色主题副文本色,外部可覆盖 - try { if (app.isDarkTheme && app.isDarkTheme()) lb.setTextColor(this.colors.textSecDark); } catch(e){} + try { if (app.isDarkTheme && app.isDarkTheme()) lb.setTextColor(this.colors.textSecDark); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } lb.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 12); var lpLb = new android.widget.LinearLayout.LayoutParams(0, -2); lpLb.weight = 1; @@ -164,14 +164,14 @@ FloatBallAppWM.prototype.ui = { et.setText(initVal ? String(initVal) : ""); et.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 14); et.setTextColor(this.colors.textPriLight); - try { if (app.isDarkTheme && app.isDarkTheme()) et.setTextColor(this.colors.textPriDark); } catch(e){} + try { if (app.isDarkTheme && app.isDarkTheme()) et.setTextColor(this.colors.textPriDark); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } // 输入框背景优化 var strokeColor = this.colors.dividerLight; - try { if (app.isDarkTheme && app.isDarkTheme()) strokeColor = this.colors.dividerDark; } catch(e){} + try { if (app.isDarkTheme && app.isDarkTheme()) strokeColor = this.colors.dividerDark; } catch(e) { safeLog(null, 'e', "catch " + String(e)); } var bg = this.createStrokeDrawable(this.colors.inputBgLight, strokeColor, app.dp(1), app.dp(8)); - try { if (app.isDarkTheme && app.isDarkTheme()) bg = this.createStrokeDrawable(this.colors.inputBgDark, strokeColor, app.dp(1), app.dp(8)); } catch(e){} + try { if (app.isDarkTheme && app.isDarkTheme()) bg = this.createStrokeDrawable(this.colors.inputBgDark, strokeColor, app.dp(1), app.dp(8)); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } et.setBackground(bg); et.setPadding(app.dp(8), app.dp(8), app.dp(8), app.dp(8)); @@ -234,10 +234,10 @@ FloatBallAppWM.prototype.ui = { } else { errTv.setVisibility(android.view.View.GONE); var strokeColor = self.colors.dividerLight; - try { if (app.isDarkTheme && app.isDarkTheme()) strokeColor = self.colors.dividerDark; } catch(e){} + try { if (app.isDarkTheme && app.isDarkTheme()) strokeColor = self.colors.dividerDark; } catch(e) { safeLog(null, 'e', "catch " + String(e)); } var normalBg = self.createStrokeDrawable(self.colors.inputBgLight, strokeColor, app.dp(1), app.dp(8)); - try { if (app.isDarkTheme && app.isDarkTheme()) normalBg = self.createStrokeDrawable(self.colors.inputBgDark, strokeColor, app.dp(1), app.dp(8)); } catch(e){} + try { if (app.isDarkTheme && app.isDarkTheme()) normalBg = self.createStrokeDrawable(self.colors.inputBgDark, strokeColor, app.dp(1), app.dp(8)); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } et.setBackground(normalBg); } } @@ -256,7 +256,7 @@ FloatBallAppWM.prototype.ui = { bgDr.setColor(bgColor); bgDr.setCornerRadius(app.dp(16)); panel.setBackground(bgDr); - try { panel.setElevation(app.dp(8)); } catch(e){} + try { panel.setElevation(app.dp(8)); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } var p = (paddingDp !== undefined) ? app.dp(paddingDp) : app.dp(16); panel.setPadding(p, p, p, p); @@ -315,7 +315,7 @@ function _th_log(L, level, msg) { if (level === "w" && L.w) { L.w(msg); return; } if (level === "i" && L.i) { L.i(msg); return; } if (L.d) { L.d(msg); return; } - } catch (e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } // =======================【莫奈动态取色工具】====================== @@ -328,7 +328,7 @@ var MonetColorProvider = { var res = android.content.res.Resources.getSystem(); var id = res.getIdentifier(resName, "color", "android"); if (id > 0) return res.getColor(id, null); - } catch (e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } try { return android.graphics.Color.parseColor(fallbackHex); } catch (e) { return 0; } }, @@ -418,9 +418,9 @@ var MonetColorProvider = { try { var id = res.getIdentifier(map[name], "color", "android"); if (id > 0) c[name] = res.getColor(id, null); - } catch (e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } - } catch (e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } return c; }, @@ -487,14 +487,14 @@ function startActivityAsUserSafe(ctx, intent, userId) { // 降级到普通启动 try { ctx.startActivity(intent); - } catch (e2) {} + } catch(e2) { safeLog(null, 'e', "catch " + String(e2)); } } } FloatBallAppWM.prototype.isDarkTheme = function() { // 0) 优先检查用户强制设置 (0=跟随系统, 1=白天, 2=黑夜) var mode = 0; - try { mode = Math.floor(Number(this.config.THEME_MODE || 0)); } catch(e){} + try { mode = Math.floor(Number(this.config.THEME_MODE || 0)); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } if (mode === 2) return true; if (mode === 1) return false; @@ -511,7 +511,7 @@ FloatBallAppWM.prototype.isDarkTheme = function() { var nightMask = (uiMode & android.content.res.Configuration.UI_MODE_NIGHT_MASK); if (nightMask === android.content.res.Configuration.UI_MODE_NIGHT_YES) { result = true; from = "Configuration(UI_MODE_NIGHT_YES)"; } else if (nightMask === android.content.res.Configuration.UI_MODE_NIGHT_NO) { result = false; from = "Configuration(UI_MODE_NIGHT_NO)"; } - } catch (e1) {} + } catch(e1) { safeLog(null, 'e', "catch " + String(e1)); } if (from === "unknown") { try { @@ -523,7 +523,7 @@ FloatBallAppWM.prototype.isDarkTheme = function() { else if (nm === android.app.UiModeManager.MODE_NIGHT_NO) { result = false; from = "UiModeManager(MODE_NIGHT_NO)"; } else { from = "UiModeManager(mode=" + String(nm) + ")"; } } - } catch (e2) {} + } catch(e2) { safeLog(null, 'e', "catch " + String(e2)); } } // # 3) 实在判断不了,就按"非暗色"处理,避免自动主题背景黑成一片 @@ -533,14 +533,14 @@ FloatBallAppWM.prototype.isDarkTheme = function() { var logKey = String(result) + "|" + from + "|" + mode; if (this._lastDarkThemeLog !== logKey) { this._lastDarkThemeLog = logKey; - try { _th_log(this.L, "d", "[theme] isDarkTheme=" + String(result) + " via=" + from + " mode=" + mode); } catch (e3) {} + try { _th_log(this.L, "d", "[theme] isDarkTheme=" + String(result) + " via=" + from + " mode=" + mode); } catch(e3) { safeLog(null, 'e', "catch " + String(e3)); } } // # 主题切换时刷新莫奈配色(传入 result 避免递归) // 注:构造函数中会初始化,这里只在构造完成后的切换时触发 if (this._lastDarkResult !== undefined && this._lastDarkResult !== result) { this._lastDarkResult = result; - try { this.refreshMonetColors(result); } catch (eM) {} + try { this.refreshMonetColors(result); } catch(eM) { safeLog(null, 'e', "catch " + String(eM)); } } else if (this._lastDarkResult === undefined) { this._lastDarkResult = result; } @@ -592,9 +592,9 @@ FloatBallAppWM.prototype.refreshMonetColors = function(forceDark) { c._monetSecondary = m.secondary; c._monetTertiary = m.tertiary; - try { _th_log(this.L, "d", "[monet] refreshed isDark=" + isDark + " primary=" + _th_hex(c.primary) + " primaryDark=" + _th_hex(c.primaryDark) + " accent=" + _th_hex(c.accent)); } catch (e) {} + try { _th_log(this.L, "d", "[monet] refreshed isDark=" + isDark + " primary=" + _th_hex(c.primary) + " primaryDark=" + _th_hex(c.primaryDark) + " accent=" + _th_hex(c.accent)); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } catch (e) { - try { _th_log(this.L, "e", "[monet] refresh err=" + String(e)); } catch (e2) {} + try { _th_log(this.L, "e", "[monet] refresh err=" + String(e)); } catch(e2) { safeLog(null, 'e', "catch " + String(e2)); } } }; @@ -618,12 +618,12 @@ FloatBallAppWM.prototype.getMonetAccentForBall = function() { var logKey = "hit|" + names[i] + "|" + c; if (this._lastAccentLog !== logKey) { this._lastAccentLog = logKey; - try { _th_log(this.L, "d", "[theme] hit accent=" + names[i] + " id=" + String(id) + " c=" + _th_hex(c) + " " + _th_argb(c)); } catch (eL0) {} + try { _th_log(this.L, "d", "[theme] hit accent=" + names[i] + " id=" + String(id) + " c=" + _th_hex(c) + " " + _th_argb(c)); } catch(eL0) { safeLog(null, 'e', "catch " + String(eL0)); } } return c; } } catch (e) { - try { _th_log(this.L, "w", "[theme] err accent=" + names[i] + " e=" + String(e)); } catch (eL2) {} + try { _th_log(this.L, "w", "[theme] err accent=" + names[i] + " e=" + String(e)); } catch(eL2) { safeLog(null, 'e', "catch " + String(eL2)); } } } @@ -634,7 +634,7 @@ FloatBallAppWM.prototype.getMonetAccentForBall = function() { var logKeyFb = "miss_all|" + fb; if (this._lastAccentLog !== logKeyFb) { this._lastAccentLog = logKeyFb; - try { _th_log(this.L, "w", "[theme] accent miss all, fallback=" + _th_hex(fb) + " " + _th_argb(fb)); } catch (eL3) {} + try { _th_log(this.L, "w", "[theme] accent miss all, fallback=" + _th_hex(fb) + " " + _th_argb(fb)); } catch(eL3) { safeLog(null, 'e', "catch " + String(eL3)); } } return fb; }; @@ -649,14 +649,14 @@ FloatBallAppWM.prototype.updateBallContentBackground = function(contentView) { // # 自定义 PNG/APP 模式下:背景透明 var fillColor = ballColor; var _usedKind = "none"; - try { _usedKind = this.state.usedIconKind || "none"; } catch(eK){} + try { _usedKind = this.state.usedIconKind || "none"; } catch(eK) { safeLog(null, 'e', "catch " + String(eK)); } try { var _pngModeBg = Number(this.config.BALL_PNG_MODE || 0); if ((_pngModeBg === 1 && _usedKind === "file") || _usedKind === "app") { fillColor = android.graphics.Color.TRANSPARENT; } - } catch (eBg) {} + } catch(eBg) { safeLog(null, 'e', "catch " + String(eBg)); } var content = new android.graphics.drawable.GradientDrawable(); content.setShape(android.graphics.drawable.GradientDrawable.OVAL); @@ -671,7 +671,7 @@ FloatBallAppWM.prototype.updateBallContentBackground = function(contentView) { ? Color.parseColor("#33000000") // 浅球用半透明黑边 : Color.parseColor("#55FFFFFF"); // 深球用半透明白边 content.setStroke(this.dp(1), strokeInt); - } catch(eS){} + } catch(eS) { safeLog(null, 'e', "catch " + String(eS)); } } var mask = new android.graphics.drawable.GradientDrawable(); @@ -683,7 +683,7 @@ FloatBallAppWM.prototype.updateBallContentBackground = function(contentView) { content, mask )); - } catch (e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } }; @@ -720,7 +720,7 @@ FloatBallAppWM.prototype.getPanelBgColorInt = function() { var out = this.withAlpha(base, a); - try { _th_log(this.L, "d", "[t]bg isDark=" + isDark + " o=" + _th_hex(out)); } catch (e2) {} + try { _th_log(this.L, "d", "[t]bg isDark=" + isDark + " o=" + _th_hex(out)); } catch(e2) { safeLog(null, 'e', "catch " + String(e2)); } return out; }; @@ -757,7 +757,7 @@ FloatBallAppWM.prototype.applyTextColorRecursive = function(v, colorInt) { this.applyTextColorRecursive(v.getChildAt(i), colorInt); } } - } catch (e0) {} + } catch(e0) { safeLog(null, 'e', "catch " + String(e0)); } }; FloatBallAppWM.prototype.updatePanelBackground = function(panelView) { @@ -774,15 +774,15 @@ FloatBallAppWM.prototype.updatePanelBackground = function(panelView) { var isDark = this.isDarkTheme(); var outlineColor = this.ui.colors._monetOutline || (isDark ? android.graphics.Color.parseColor("#8E918F") : android.graphics.Color.parseColor("#747775")); var stroke = this.withAlpha(outlineColor, isDark ? 0.26 : 0.20); - try { bg.setStroke(sw, stroke); } catch (eS) {} + try { bg.setStroke(sw, stroke); } catch(eS) { safeLog(null, 'e', "catch " + String(eS)); } panelView.setBackground(bg); var tc = this.getPanelTextColorInt(bgInt); - try { themeBgInt = bgInt; themeTextInt = tc; } catch (eT) {} + try { themeBgInt = bgInt; themeTextInt = tc; } catch(eT) { safeLog(null, 'e', "catch " + String(eT)); } this.applyTextColorRecursive(panelView, tc); - try { _th_log(this.L, "d", "[t]apply bg=" + _th_hex(bgInt) + " tx=" + _th_hex(tc)); } catch (e) {} + try { _th_log(this.L, "d", "[t]apply bg=" + _th_hex(bgInt) + " tx=" + _th_hex(tc)); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } try { @@ -792,9 +792,9 @@ FloatBallAppWM.prototype.updatePanelBackground = function(panelView) { " text=" + _th_hex(tc) + " " + _th_argb(tc) + " stroke=" + _th_hex(stroke) ); - } catch (eL0) {} + } catch(eL0) { safeLog(null, 'e', "catch " + String(eL0)); } } catch (e) { - try { _th_log(this.L, "e", "[theme:apply] err=" + String(e)); } catch (eL1) {} + try { _th_log(this.L, "e", "[theme:apply] err=" + String(e)); } catch(eL1) { safeLog(null, 'e', "catch " + String(eL1)); } } }; diff --git a/code/th_05_persistence.js b/code/th_05_persistence.js index ab2f937..9ebe4dd 100644 --- a/code/th_05_persistence.js +++ b/code/th_05_persistence.js @@ -8,7 +8,7 @@ FloatBallAppWM.prototype.savePanelState = function(key, state) { // 节流或立即保存? 面板拖动结束通常不频繁,立即保存即可 // 但为了避免连续事件,还是可以复用 savePos 的节流逻辑,或者直接保存 ConfigManager.saveSettings(this.config); - } catch (e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } }; FloatBallAppWM.prototype.loadPanelState = function(key) { @@ -174,7 +174,7 @@ FloatBallAppWM.prototype._refreshPreviewInternal = function(changedKey) { // 移除旧面板 if (oldAdded && oldPanel) { - try { this.state.wm.removeView(oldPanel); } catch(e) {} + try { this.state.wm.removeView(oldPanel); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } } @@ -208,7 +208,7 @@ FloatBallAppWM.prototype.applyImmediateEffectsForKey = function(k) { this.L.cfg.LOG_ENABLE = !!this.config.LOG_ENABLE; this.L.i("apply LOG_ENABLE=" + String(this.config.LOG_ENABLE)); } - } catch (eLE) {} + } catch(eLE) { safeLog(null, 'e', "catch " + String(eLE)); } return; } if (k === "LOG_DEBUG") { @@ -218,7 +218,7 @@ FloatBallAppWM.prototype.applyImmediateEffectsForKey = function(k) { this.L.cfg.LOG_DEBUG = !!this.config.LOG_DEBUG; this.L.i("apply LOG_DEBUG=" + String(this.config.LOG_DEBUG)); } - } catch (eLD) {} + } catch(eLD) { safeLog(null, 'e', "catch " + String(eLD)); } return; } if (k === "LOG_KEEP_DAYS") { @@ -231,7 +231,7 @@ FloatBallAppWM.prototype.applyImmediateEffectsForKey = function(k) { this.L.i("apply LOG_KEEP_DAYS=" + String(n)); this.L.cleanupOldFiles(); } - } catch (eLK) {} + } catch(eLK) { safeLog(null, 'e', "catch " + String(eLK)); } return; } if (k === "BALL_SIZE_DP" || k === "BALL_PNG_MODE" || k === "BALL_ICON_TYPE" || k === "BALL_ICON_FILE_PATH" || k === "BALL_ICON_RES_ID" || k === "BALL_ICON_RES_NAME" || k === "BALL_ICON_SIZE_DP" || k === "BALL_ICON_TINT_HEX") { this.rebuildBallForNewSize(); return; } @@ -255,7 +255,7 @@ FloatBallAppWM.prototype.applyImmediateEffectsForKey = function(k) { } return; } - } catch (e0) {} + } catch(e0) { safeLog(null, 'e', "catch " + String(e0)); } }; FloatBallAppWM.prototype.commitPendingUserCfg = function() { diff --git a/code/th_06_icon_parser.js b/code/th_06_icon_parser.js index dd16ae4..3bc5205 100644 --- a/code/th_06_icon_parser.js +++ b/code/th_06_icon_parser.js @@ -51,7 +51,7 @@ FloatBallAppWM.prototype.resolveIconDrawable = function(btn) { var dr = this.loadBallIconDrawableFromFile(path, this.dp(sizeDp), 1048576, 1024); if (dr) return dr; } - } catch (ePath) {} + } catch(ePath) { safeLog(null, 'e', "catch " + String(ePath)); } } @@ -74,7 +74,7 @@ try { } } } -} catch (eApp) {} + } catch(eApp) { safeLog(null, 'e', "catch " + String(eApp)); } // # 1.5) type=shortcut:尝试取 Shortcuts 快捷方式图标(显示与 shortcuts.js 页面一致) @@ -100,13 +100,13 @@ try { try { var sk0 = pkg2 + "@" + sid2 + "@" + (btn.userId != null ? String(btn.userId) : ""); this._iconLruPut("sc|" + sk0, dr0); - } catch (eSc0) {} + } catch(eSc0) { safeLog(null, 'e', "catch " + String(eSc0)); } return dr0; } } - } catch(eF0) {} + } catch(eF0) { safeLog(null, 'e', "catch " + String(eF0)); } } - } catch(eFile0) {} + } catch(eFile0) { safeLog(null, 'e', "catch " + String(eFile0)); } var skey = pkg2 + "@" + sid2 + "@" + (btn.userId != null ? String(btn.userId) : ""); var kSc = "sc|" + skey; var hitSc = this._iconLruGet(kSc); @@ -145,7 +145,7 @@ var skey = pkg2 + "@" + sid2 + "@" + (btn.userId != null ? String(btn.userId) : var tmpUid2 = parseInt(String(buid2), 10); if (!isNaN(tmpUid2)) userIdIntForSvc = tmpUid2; } - } catch(eUidSvc) {} + } catch(eUidSvc) { safeLog(null, 'e', "catch " + String(eUidSvc)); } var sm2 = android.os.ServiceManager; var shortcutSvc = null; @@ -160,23 +160,23 @@ var skey = pkg2 + "@" + sid2 + "@" + (btn.userId != null ? String(btn.userId) : if (listObj2) list = listObj2; } } - } catch(eSvc2) {} + } catch(eSvc2) { safeLog(null, 'e', "catch " + String(eSvc2)); } // # 2) LauncherApps 回退(当 shortcut service 不可用或返回空时) if (list == null) { var q = new android.content.pm.LauncherApps.ShortcutQuery(); - try { q.setPackage(pkg2); } catch(eSP) {} + try { q.setPackage(pkg2); } catch(eSP) { safeLog(null, 'e', "catch " + String(eSP)); } // # 重要:必须设置 QueryFlags,否则 getShortcuts 可能返回空(默认 flags=0) // # 兼容性:不同 Android/ROM 可能缺少部分 FLAG,逐个 try 叠加 try { var qFlags = 0; - try { qFlags = qFlags | android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_DYNAMIC; } catch(eF1) {} - try { qFlags = qFlags | android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_PINNED; } catch(eF2) {} - try { qFlags = qFlags | android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_MANIFEST; } catch(eF3) {} - try { qFlags = qFlags | android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_CACHED; } catch(eF4) {} - try { q.setQueryFlags(qFlags); } catch(eSF) {} - } catch(eQF) {} + try { qFlags = qFlags | android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_DYNAMIC; } catch(eF1) { safeLog(null, 'e', "catch " + String(eF1)); } + try { qFlags = qFlags | android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_PINNED; } catch(eF2) { safeLog(null, 'e', "catch " + String(eF2)); } + try { qFlags = qFlags | android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_MANIFEST; } catch(eF3) { safeLog(null, 'e', "catch " + String(eF3)); } + try { qFlags = qFlags | android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_CACHED; } catch(eF4) { safeLog(null, 'e', "catch " + String(eF4)); } + try { q.setQueryFlags(qFlags); } catch(eSF) { safeLog(null, 'e', "catch " + String(eSF)); } + } catch(eQF) { safeLog(null, 'e', "catch " + String(eQF)); } // # 重要:用户句柄优先用按钮携带的 userId(如有),否则使用当前用户 var uh = android.os.Process.myUserHandle(); @@ -190,7 +190,7 @@ var skey = pkg2 + "@" + sid2 + "@" + (btn.userId != null ? String(btn.userId) : uh = android.os.UserHandle.of(uidInt); } } - } catch(eUH) {} + } catch(eUH) { safeLog(null, 'e', "catch " + String(eUH)); } try { list = la.getShortcuts(q, uh); } catch(eGS) { list = null; } } @@ -219,10 +219,10 @@ if (si != null) { var d2 = ic.loadDrawable(context); if (d2 != null) drSc = d2; } - } catch(eIcon1) {} + } catch(eIcon1) { safeLog(null, 'e', "catch " + String(eIcon1)); } } if (drSc != null) { - try { this._iconLruPut("sc|" + skey, drSc); } catch (eSc1) {} + try { this._iconLruPut("sc|" + skey, drSc); } catch(eSc1) { safeLog(null, 'e', "catch " + String(eSc1)); } return drSc; } } @@ -235,7 +235,7 @@ if (si != null) { try { if (nowTs > 0) this._shortcutIconFailTs[skey] = nowTs; else this._shortcutIconFailTs[skey] = new Date().getTime(); - } catch(eFT) {} + } catch(eFT) { safeLog(null, 'e', "catch " + String(eFT)); } } @@ -244,10 +244,10 @@ if (si != null) { var pm2 = context.getPackageManager(); var drApp2 = pm2.getApplicationIcon(pkg2); if (drApp2 != null) return drApp2; - } catch(eFall) {} + } catch(eFall) { safeLog(null, 'e', "catch " + String(eFall)); } } } - } catch (eSc) {} + } catch(eSc) { safeLog(null, 'e', "catch " + String(eSc)); } // # 2) 显式指定 iconResName (String) 或 iconResId (int) try { if (btn.iconResName) { @@ -259,11 +259,11 @@ if (si != null) { if (id > 0) return context.getResources().getDrawable(id, null); } if (btn.iconResId) return context.getResources().getDrawable(btn.iconResId, null); - } catch (e1) {} + } catch(e1) { safeLog(null, 'e', "catch " + String(e1)); } // # 3) 兜底 return context.getResources().getDrawable(android.R.drawable.ic_menu_help, null); - } catch (e2) {} + } catch(e2) { safeLog(null, 'e', "catch " + String(e2)); } return null; }; @@ -302,7 +302,7 @@ FloatBallAppWM.prototype.normalizeShortXIconName = function(name, keepPrefix) { return s; } return keepPrefix ? ("ic_remix_" + s) : s; - } catch (e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } return ""; }; @@ -320,20 +320,20 @@ FloatBallAppWM.prototype.getShortXApkPaths = function() { p = String(p || ""); if (!p) return; if (out.indexOf(p) < 0) out.push(p); - } catch (eP) {} + } catch(eP) { safeLog(null, 'e', "catch " + String(eP)); } } if (ai) { - try { pushPath(ai.sourceDir); } catch (e0) {} - try { pushPath(ai.publicSourceDir); } catch (e1) {} + try { pushPath(ai.sourceDir); } catch(e0) { safeLog(null, 'e', "catch " + String(e0)); } + try { pushPath(ai.publicSourceDir); } catch(e1) { safeLog(null, 'e', "catch " + String(e1)); } try { var ss = ai.splitSourceDirs; if (ss) { var i; for (i = 0; i < ss.length; i++) pushPath(ss[i]); } - } catch (e2) {} + } catch(e2) { safeLog(null, 'e', "catch " + String(e2)); } } - } catch (e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } return out; }; @@ -371,7 +371,7 @@ FloatBallAppWM.prototype.scanShortXIconsFromApk = function() { } catch (eZip) { lastErr = String(eZip); } finally { - try { if (zip) zip.close(); } catch (eClose) {} + try { if (zip) zip.close(); } catch(eClose) { safeLog(null, 'e', "catch " + String(eClose)); } } } if ((!out || out.length === 0) && lastErr) this._shortxIconCatalogError = "APK扫描: " + lastErr + " (路径数=" + paths.length + ", 文件数=" + totalFiles + ")"; @@ -399,7 +399,7 @@ FloatBallAppWM.prototype.getShortXIconLookupNames = function(name) { add("ic_remix_" + s); add("ic_" + s); } - } catch (e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } return out; }; @@ -414,7 +414,7 @@ FloatBallAppWM.prototype.resolveShortXDrawableResId = function(name) { try { resId = handle.res.getIdentifier(String(cands[i]), "drawable", handle.pkg); } catch (e1) { resId = 0; } if (resId > 0) return resId; } - } catch (e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } return 0; }; @@ -429,10 +429,10 @@ FloatBallAppWM.prototype.resolveShortXDrawable = function(name, tintHex) { try { dr = dr.mutate(); dr.setColorFilter(android.graphics.Color.parseColor(String(tintHex)), android.graphics.PorterDuff.Mode.SRC_IN); - } catch (eTint) {} + } catch(eTint) { safeLog(null, 'e', "catch " + String(eTint)); } } return dr; - } catch (e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } return null; }; @@ -467,7 +467,7 @@ FloatBallAppWM.prototype.getShortXIconCatalog = function(forceReload) { shortName: (fname.indexOf("ic_remix_") === 0) ? fname.substring("ic_remix_".length) : fname, id: f.getInt(null) }); - } catch (eField) {} + } catch(eField) { safeLog(null, 'e', "catch " + String(eField)); } } } catch (eClz) { this._shortxIconCatalogError = "R$drawable reflect: " + String(eClz); diff --git a/code/th_07_shortcut.js b/code/th_07_shortcut.js index 3aa9d40..3c04ea3 100644 --- a/code/th_07_shortcut.js +++ b/code/th_07_shortcut.js @@ -42,7 +42,7 @@ FloatBallAppWM.prototype.showShortcutPicker = function(opts) { self.__shortcutPickerSingleton.show(opts); return; } - } catch(eSingle) {} + } catch(eSingle) { safeLog(null, 'e', "catch " + String(eSingle)); } // # 兼容:toolhub.js 全局未必定义 Context 别名,这里显式绑定,避免 ReferenceError。 @@ -76,7 +76,7 @@ FloatBallAppWM.prototype.showShortcutPicker = function(opts) { if (f.exists() && f.isDirectory() && f.canRead()) { return candidates[i]; } - } catch(e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } // 反射获取环境变量(最可靠但较慢) @@ -89,7 +89,7 @@ FloatBallAppWM.prototype.showShortcutPicker = function(opts) { return envPath; } } - } catch(e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } // 最终兜底 return "/data/system_ce"; @@ -119,7 +119,7 @@ FloatBallAppWM.prototype.showShortcutPicker = function(opts) { if (!ok) continue; out.push(parseInt(name, 10)); } - } catch(e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } // 默认兜底:至少有 user 0 if (out.length === 0) out.push(0); return out; @@ -135,7 +135,7 @@ FloatBallAppWM.prototype.showShortcutPicker = function(opts) { if (typeof getSystemUserDir === "function") { basePath = getSystemUserDir(); } - } catch(eGSD2) {} + } catch(eGSD2) { safeLog(null, 'e', "catch " + String(eGSD2)); } var dir = new java.io.File(basePath + "/" + String(userId) + "/shortcut_service/packages"); if (!dir.exists() || !dir.isDirectory()) return out; @@ -151,7 +151,7 @@ FloatBallAppWM.prototype.showShortcutPicker = function(opts) { if (pkg && pkg.length > 0) out.push(pkg); } } - } catch(e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } return out; } @@ -187,9 +187,9 @@ FloatBallAppWM.prototype.showShortcutPicker = function(opts) { try { var s0 = listObj.get(si0); if (s0) out.push(s0); - } catch(eS2) {} + } catch(eS2) { safeLog(null, 'e', "catch " + String(eS2)); } } - } catch(eS3) {} + } catch(eS3) { safeLog(null, 'e', "catch " + String(eS3)); } if (out.length > 0) return out; } } @@ -222,9 +222,9 @@ FloatBallAppWM.prototype.showShortcutPicker = function(opts) { LauncherAppsShortcutQuery.FLAG_MATCH_PINNED | LauncherAppsShortcutQuery.FLAG_MATCH_MANIFEST ); - } catch(eF2) {} + } catch(eF2) { safeLog(null, 'e', "catch " + String(eF2)); } } - try { q.setPackage(safeStr(pkg)); } catch(eP) {} + try { q.setPackage(safeStr(pkg)); } catch(eP) { safeLog(null, 'e', "catch " + String(eP)); } // user 处理:尽量兼容多用户 var userHandle = null; @@ -248,9 +248,9 @@ FloatBallAppWM.prototype.showShortcutPicker = function(opts) { try { var si = list.get(i); if (si) out.push(si); - } catch(eI) {} + } catch(eI) { safeLog(null, 'e', "catch " + String(eI)); } } - } catch(e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } return out; } @@ -261,7 +261,7 @@ FloatBallAppWM.prototype.showShortcutPicker = function(opts) { var ai = pm.getApplicationInfo(String(pkg), 0); var lb = pm.getApplicationLabel(ai); if (lb != null) return String(lb); - } catch(e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } return String(pkg); } @@ -315,14 +315,14 @@ FloatBallAppWM.prototype.showShortcutPicker = function(opts) { // density: 0 让系统自适应(部分 ROM 更稳) var dr = la.getShortcutIconDrawable(item.shortcutInfo, 0); if (dr) return dr; - } catch(eLa) {} + } catch(eLa) { safeLog(null, 'e', "catch " + String(eLa)); } } - } catch(e0) {} + } catch(e0) { safeLog(null, 'e', "catch " + String(e0)); } // fallback: app icon try { var pm = context.getPackageManager(); return pm.getApplicationIcon(String(item.pkg)); - } catch(e1) {} + } catch(e1) { safeLog(null, 'e', "catch " + String(e1)); } return null; } @@ -357,7 +357,7 @@ FloatBallAppWM.prototype.showShortcutPicker = function(opts) { return ta.localeCompare(tb); }); order = ["__ALL__"].concat(rest); - } catch(eS) {} + } catch(eS) { safeLog(null, 'e', "catch " + String(eS)); } return { groups: groups, order: order }; } @@ -440,13 +440,13 @@ FloatBallAppWM.prototype.showShortcutPicker = function(opts) { }; - function Ld(msg) { try { if (self.L) self.L.d("[shortcut] " + msg); } catch(e) {} } - function Li(msg) { try { if (self.L) self.L.i("[shortcut] " + msg); } catch(e) {} } - function Le(msg) { try { if (self.L) self.L.e("[shortcut] " + msg); } catch(e) {} } + function Ld(msg) { try { if (self.L) self.L.d("[shortcut] " + msg); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } + function Li(msg) { try { if (self.L) self.L.i("[shortcut] " + msg); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } + function Le(msg) { try { if (self.L) self.L.e("[shortcut] " + msg); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } function runOn(handler, fn) { try { - handler.post(new JavaAdapter(Runnable, { run: function() { try { fn(); } catch(e) {} } })); + handler.post(new JavaAdapter(Runnable, { run: function() { try { fn(); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } })); return true; } catch(e) { return false; } } @@ -462,45 +462,45 @@ FloatBallAppWM.prototype.showShortcutPicker = function(opts) { state.scrollPollRunning = false; // # 停止队列与异步:隐藏后不再触发 UI/图标加载逻辑 - try { h.removeCallbacksAndMessages(null); } catch(eCB0) {} - try { bgH.removeCallbacksAndMessages(null); } catch(eCB1) {} + try { h.removeCallbacksAndMessages(null); } catch(eCB0) { safeLog(null, 'e', "catch " + String(eCB0)); } + try { bgH.removeCallbacksAndMessages(null); } catch(eCB1) { safeLog(null, 'e', "catch " + String(eCB1)); } // # 输入法/焦点:无论是否弹出输入法,都先退焦点并尝试隐藏软键盘 try { if (state.etSearch) { - try { state.etSearch.clearFocus(); } catch(eK0) {} + try { state.etSearch.clearFocus(); } catch(eK0) { safeLog(null, 'e', "catch " + String(eK0)); } try { var imm = context.getSystemService(android.content.Context.INPUT_METHOD_SERVICE); if (imm) imm.hideSoftInputFromWindow(state.etSearch.getWindowToken(), 0); - } catch(eK1) {} + } catch(eK1) { safeLog(null, 'e', "catch " + String(eK1)); } } - } catch(eK2) {} + } catch(eK2) { safeLog(null, 'e', "catch " + String(eK2)); } // # 仅隐藏 View:不触碰 WM removeView,避免 WM/IME token 状态机被打乱 try { if (state.root) { state.root.setVisibility(android.view.View.GONE); } - } catch(eV0) {} + } catch(eV0) { safeLog(null, 'e', "catch " + String(eV0)); } // # 退出线程:hide 时也释放线程,避免反复打开/隐藏导致线程堆积 try { var killer = new Thread(new JavaAdapter(Runnable, { run: function() { - try { bgHt.quitSafely(); } catch(e2) {} - try { ht.quitSafely(); } catch(e3) {} + try { bgHt.quitSafely(); } catch(e2) { safeLog(null, 'e', "catch " + String(e2)); } + try { ht.quitSafely(); } catch(e3) { safeLog(null, 'e', "catch " + String(e3)); } } })); killer.start(); - } catch(eQuit) {} + } catch(eQuit) { safeLog(null, 'e', "catch " + String(eQuit)); } // # 通知外层:选择器已隐藏,可恢复上层面板显示 try { if (state.onDismiss && !state.onDismissCalled) { state.onDismissCalled = true; - try { state.onDismiss(); } catch(eOD0) {} + try { state.onDismiss(); } catch(eOD0) { safeLog(null, 'e', "catch " + String(eOD0)); } } - } catch(eOD1) {} + } catch(eOD1) { safeLog(null, 'e', "catch " + String(eOD1)); } }); } @@ -516,51 +516,51 @@ FloatBallAppWM.prototype.showShortcutPicker = function(opts) { state.scrollPollRunning = false; // # 清理消息队列 - try { h.removeCallbacksAndMessages(null); } catch(eCB0) {} - try { bgH.removeCallbacksAndMessages(null); } catch(eCB1) {} + try { h.removeCallbacksAndMessages(null); } catch(eCB0) { safeLog(null, 'e', "catch " + String(eCB0)); } + try { bgH.removeCallbacksAndMessages(null); } catch(eCB1) { safeLog(null, 'e', "catch " + String(eCB1)); } - try { state.iconQ = []; } catch(e0) {} + try { state.iconQ = []; } catch(e0) { safeLog(null, 'e', "catch " + String(e0)); } state.iconInFlight = 0; // # 通知外层:选择器即将销毁,可恢复上层面板显示 try { if (state.onDismiss && !state.onDismissCalled) { state.onDismissCalled = true; - try { state.onDismiss(); } catch(eOD0) {} + try { state.onDismiss(); } catch(eOD0) { safeLog(null, 'e', "catch " + String(eOD0)); } } - } catch(eOD1) {} + } catch(eOD1) { safeLog(null, 'e', "catch " + String(eOD1)); } // # 输入法/焦点清理 try { if (state.etSearch) { - try { state.etSearch.clearFocus(); } catch(eK0) {} + try { state.etSearch.clearFocus(); } catch(eK0) { safeLog(null, 'e', "catch " + String(eK0)); } try { var imm = context.getSystemService(android.content.Context.INPUT_METHOD_SERVICE); if (imm) imm.hideSoftInputFromWindow(state.etSearch.getWindowToken(), 0); - } catch(eK1) {} + } catch(eK1) { safeLog(null, 'e', "catch " + String(eK1)); } } - } catch(eK2) {} + } catch(eK2) { safeLog(null, 'e', "catch " + String(eK2)); } // # 尝试移除 View(失败也吞掉,避免把 system_server 再次打穿) var rootRef = state.root; var wasAdded = state.isAdded; try { if (rootRef && wasAdded) { - try { wm.removeViewImmediate(rootRef); } catch(eR0) { try { wm.removeView(rootRef); } catch(eR1) {} } + try { wm.removeViewImmediate(rootRef); } catch(eR0) { try { wm.removeView(rootRef); } catch(eR1) { safeLog(null, 'e', "catch " + String(eR1)); } } } - } catch(eR2) {} + } catch(eR2) { safeLog(null, 'e', "catch " + String(eR2)); } state.isAdded = false; state.root = null; // # 单例清理 - try { if (self.__shortcutPickerSingleton && self.__shortcutPickerSingleton.instanceId === state.instanceId) self.__shortcutPickerSingleton = null; } catch(eS0) {} + try { if (self.__shortcutPickerSingleton && self.__shortcutPickerSingleton.instanceId === state.instanceId) self.__shortcutPickerSingleton = null; } catch(eS0) { safeLog(null, 'e', "catch " + String(eS0)); } // # 退出线程 var killer = new Thread(new JavaAdapter(Runnable, { run: function() { - try { bgHt.quitSafely(); } catch(e2) {} - try { ht.quitSafely(); } catch(e3) {} + try { bgHt.quitSafely(); } catch(e2) { safeLog(null, 'e', "catch " + String(e2)); } + try { ht.quitSafely(); } catch(e3) { safeLog(null, 'e', "catch " + String(e3)); } } })); killer.start(); @@ -633,7 +633,7 @@ function cacheGet(key) { if (state.destroyed) return; if (dr) { - try { j.iv.setImageDrawable(dr); } catch(e1) {} + try { j.iv.setImageDrawable(dr); } catch(e1) { safeLog(null, 'e', "catch " + String(e1)); } cachePut(j.key, dr); } else { markIconFail(j.key); @@ -645,7 +645,7 @@ function cacheGet(key) { } } - function setStat(text) { try { if (state.tvStat) state.tvStat.setText(String(text)); } catch(e) {} } + function setStat(text) { try { if (state.tvStat) state.tvStat.setText(String(text)); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } function rebuildRenderList() { var g = state.groups ? state.groups[state.currentGroupKey] : null; @@ -661,7 +661,7 @@ function cacheGet(key) { function clearGrid() { try { if (state.grid) state.grid.removeAllViews(); - } catch(e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } function appendBatch() { @@ -687,7 +687,7 @@ function cacheGet(key) { var lpRow = new android.widget.LinearLayout.LayoutParams(android.widget.LinearLayout.LayoutParams.MATCH_PARENT, android.widget.LinearLayout.LayoutParams.WRAP_CONTENT); lpRow.setMargins(0, 0, 0, self.dp(8)); row.setLayoutParams(lpRow); - } catch(eLpR) {} + } catch(eLpR) { safeLog(null, 'e', "catch " + String(eLpR)); } row.setPadding(self.dp(12), self.dp(10), self.dp(12), self.dp(10)); @@ -697,18 +697,18 @@ function cacheGet(key) { var bgColor = isDark ? self.ui.colors.cardDark : self.ui.colors.cardLight; var stroke = isDark ? self.ui.colors.dividerDark : self.ui.colors.dividerLight; row.setBackground(self.ui.createStrokeDrawable(bgColor, stroke, self.dp(1), self.dp(12))); - } catch(eBg) {} + } catch(eBg) { safeLog(null, 'e', "catch " + String(eBg)); } var iv = new android.widget.ImageView(context); var lpI = new android.widget.LinearLayout.LayoutParams(self.dp(40), self.dp(40)); lpI.setMargins(0, 0, self.dp(12), 0); iv.setLayoutParams(lpI); - try { iv.setImageResource(android.R.drawable.sym_def_app_icon); } catch(eI0) {} + try { iv.setImageResource(android.R.drawable.sym_def_app_icon); } catch(eI0) { safeLog(null, 'e', "catch " + String(eI0)); } var key = safeStr(it.pkg) + "@" + safeStr(it.id) + "@" + safeStr(it.userId); var cached = cacheGet(key); if (cached) { - try { iv.setImageDrawable(cached); } catch(eIC) {} + try { iv.setImageDrawable(cached); } catch(eIC) { safeLog(null, 'e', "catch " + String(eIC)); } } else { enqueueIconLoad(it, iv, key); } @@ -722,8 +722,8 @@ function cacheGet(key) { var tv1 = new android.widget.TextView(context); tv1.setText(safeStr(it.label || it.id || it.pkg)); tv1.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 14); - try { tv1.setTypeface(null, android.graphics.Typeface.BOLD); } catch(eB) {} - try { tv1.setTextColor(self.isDarkTheme() ? self.ui.colors.textPriDark : self.ui.colors.textPriLight); } catch(eC1) {} + try { tv1.setTypeface(null, android.graphics.Typeface.BOLD); } catch(eB) { safeLog(null, 'e', "catch " + String(eB)); } + try { tv1.setTextColor(self.isDarkTheme() ? self.ui.colors.textPriDark : self.ui.colors.textPriLight); } catch(eC1) { safeLog(null, 'e', "catch " + String(eC1)); } tv1.setSingleLine(true); tv1.setEllipsize(android.text.TextUtils.TruncateAt.END); col.addView(tv1); @@ -733,7 +733,7 @@ function cacheGet(key) { tv2.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 11); tv2.setSingleLine(true); tv2.setEllipsize(android.text.TextUtils.TruncateAt.END); - try { tv2.setTextColor(self.isDarkTheme() ? self.ui.colors.textSecDark : self.ui.colors.textSecLight); } catch(eC2) {} + try { tv2.setTextColor(self.isDarkTheme() ? self.ui.colors.textSecDark : self.ui.colors.textSecLight); } catch(eC2) { safeLog(null, 'e', "catch " + String(eC2)); } col.addView(tv2); // # pick 模式:额外显示 userId,避免多用户/工作资料混淆 @@ -742,7 +742,7 @@ function cacheGet(key) { tv3.setText("userId: " + safeStr(it.userId)); tv3.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 10); tv3.setSingleLine(true); - try { tv3.setTextColor(self.isDarkTheme() ? self.ui.colors.textSecDark : self.ui.colors.textSecLight); } catch(eC3) {} + try { tv3.setTextColor(self.isDarkTheme() ? self.ui.colors.textSecDark : self.ui.colors.textSecLight); } catch(eC3) { safeLog(null, 'e', "catch " + String(eC3)); } col.addView(tv3); } @@ -771,7 +771,7 @@ function cacheGet(key) { } catch(eStart) { self.toast("启动失败: " + eStart); } - } catch(eClick) {} + } catch(eClick) { safeLog(null, 'e', "catch " + String(eClick)); } } })); @@ -817,7 +817,7 @@ function cacheGet(key) { tv.setTextColor(isSel ? tPri : tSec); tv.setBackground(self.ui.createStrokeDrawable(bgColor, stroke, self.dp(1), self.dp(16))); - } catch(eBg) {} + } catch(eBg) { safeLog(null, 'e', "catch " + String(eBg)); } tv.setOnClickListener(new android.view.View.OnClickListener({ onClick: function() { @@ -835,7 +835,7 @@ function cacheGet(key) { state.tabRow.addView(tv); })(order[i]); } - } catch(e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } function startScrollPoll() { @@ -862,7 +862,7 @@ function cacheGet(key) { appendBatch(); } } - } catch(e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } schedule(); }); } @@ -870,7 +870,7 @@ function cacheGet(key) { function schedule() { try { h.postDelayed(new JavaAdapter(Runnable, { run: tick }), 180); - } catch(e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } schedule(); @@ -889,8 +889,8 @@ function cacheGet(key) { var title = new android.widget.TextView(context); title.setText(mode === "pick" ? "选择快捷方式" : "快捷方式浏览器"); title.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 16); - try { title.setTypeface(null, android.graphics.Typeface.BOLD); } catch(e) {} - try { title.setTextColor(self.isDarkTheme() ? self.ui.colors.textPriDark : self.ui.colors.textPriLight); } catch(e) {} + try { title.setTypeface(null, android.graphics.Typeface.BOLD); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } + try { title.setTextColor(self.isDarkTheme() ? self.ui.colors.textPriDark : self.ui.colors.textPriLight); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } var lpT = new android.widget.LinearLayout.LayoutParams(0, android.widget.LinearLayout.LayoutParams.WRAP_CONTENT); lpT.weight = 1; @@ -903,7 +903,7 @@ function cacheGet(key) { try { btnClose.setPadding(self.dp(12), self.dp(6), self.dp(12), self.dp(6)); btnClose.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 13); - } catch(e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } top.addView(title); top.addView(btnClose); @@ -916,12 +916,12 @@ function cacheGet(key) { try { et.setTextColor(self.isDarkTheme() ? self.ui.colors.textPriDark : self.ui.colors.textPriLight); et.setHintTextColor(self.isDarkTheme() ? self.ui.colors.textSecDark : self.ui.colors.textSecLight); - } catch(e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } try { var inBg = self.ui.createRoundDrawable(self.isDarkTheme() ? self.ui.colors.inputBgDark : self.ui.colors.inputBgLight, self.dp(12)); et.setBackground(inBg); - } catch(eBg) {} + } catch(eBg) { safeLog(null, 'e', "catch " + String(eBg)); } // # Tabs(横向滚动:统一为"胶囊按钮"风格,选中态更明确) var tabSv = new android.widget.HorizontalScrollView(context); @@ -930,13 +930,13 @@ function cacheGet(key) { var tabRow = new android.widget.LinearLayout(context); tabRow.setOrientation(android.widget.LinearLayout.HORIZONTAL); - try { tabRow.setPadding(0, self.dp(8), 0, self.dp(6)); } catch(e) {} + try { tabRow.setPadding(0, self.dp(8), 0, self.dp(6)); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } tabSv.addView(tabRow); // # 状态栏(数量/渲染进度) var tvStat = new android.widget.TextView(context); tvStat.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 12); - try { tvStat.setTextColor(self.isDarkTheme() ? self.ui.colors.textSecDark : self.ui.colors.textSecLight); } catch(e) {} + try { tvStat.setTextColor(self.isDarkTheme() ? self.ui.colors.textSecDark : self.ui.colors.textSecLight); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } tvStat.setPadding(0, self.dp(6), 0, self.dp(6)); // # 列表(卡片式条目列表) @@ -946,7 +946,7 @@ function cacheGet(key) { var list = new android.widget.LinearLayout(context); list.setOrientation(android.widget.LinearLayout.VERTICAL); - try { list.setPadding(0, self.dp(2), 0, self.dp(2)); } catch(e) {} + try { list.setPadding(0, self.dp(2), 0, self.dp(2)); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } sv.addView(list); // bind @@ -970,10 +970,10 @@ function cacheGet(key) { rebuildRenderList(); clearGrid(); appendBatch(); - } catch(e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } })); - } catch(eTw) {} + } catch(eTw) { safeLog(null, 'e', "catch " + String(eTw)); } // layout root.addView(top); @@ -983,7 +983,7 @@ function cacheGet(key) { var lpEt = new android.widget.LinearLayout.LayoutParams(android.widget.LinearLayout.LayoutParams.MATCH_PARENT, android.widget.LinearLayout.LayoutParams.WRAP_CONTENT); lpEt.setMargins(0, 0, 0, self.dp(8)); et.setLayoutParams(lpEt); - } catch(eLpEt) {} + } catch(eLpEt) { safeLog(null, 'e', "catch " + String(eLpEt)); } root.addView(et); root.addView(tabSv); @@ -995,7 +995,7 @@ function cacheGet(key) { root.addView(sv); // 主题:用 ToolHub 现有的背景更新逻辑兜底(防止外部主题配置影响) - try { self.updatePanelBackground(root); } catch(eTheme) {} + try { self.updatePanelBackground(root); } catch(eTheme) { safeLog(null, 'e', "catch " + String(eTheme)); } return root; } @@ -1018,19 +1018,19 @@ function cacheGet(key) { try { state.params.softInputMode = android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING | android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN; - } catch(eSIM1) {} + } catch(eSIM1) { safeLog(null, 'e', "catch " + String(eSIM1)); } try { state.params.flags = state.params.flags | android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS; - } catch(eTop1) {} + } catch(eTop1) { safeLog(null, 'e', "catch " + String(eTop1)); } var sw2 = (self.state && self.state.screen && self.state.screen.w) ? self.state.screen.w : 0; if (sw2 > 0) state.params.x = Math.max(0, Math.round((sw2 - state.params.width) / 2)); else state.params.x = 0; state.params.y = 0; wm.updateViewLayout(state.root, state.params); } - } catch(ePos2) {} + } catch(ePos2) { safeLog(null, 'e', "catch " + String(ePos2)); } // # 层级修复:同类型(TYPE_APPLICATION_OVERLAY)窗口之间的上下层由 addView 顺序决定 // # 说明:当"新增按钮页/主面板"在本窗口之后 addView 时,会把本窗口盖住;复用 show 仅 setVisibility 无法提升层级 @@ -1039,16 +1039,16 @@ function cacheGet(key) { var tsNow = now(); if (!state.lastRaiseTs || (tsNow - state.lastRaiseTs) > 300) { state.lastRaiseTs = tsNow; - try { wm.removeViewImmediate(state.root); } catch(eZ0) {} - try { wm.addView(state.root, state.params); } catch(eZ1) {} + try { wm.removeViewImmediate(state.root); } catch(eZ0) { safeLog(null, 'e', "catch " + String(eZ0)); } + try { wm.addView(state.root, state.params); } catch(eZ1) { safeLog(null, 'e', "catch " + String(eZ1)); } state.isAdded = true; } - } catch(eZ2) {} -try { state.root.setVisibility(android.view.View.VISIBLE); } catch(eVis) {} + } catch(eZ2) { safeLog(null, 'e', "catch " + String(eZ2)); } +try { state.root.setVisibility(android.view.View.VISIBLE); } catch(eVis) { safeLog(null, 'e', "catch " + String(eVis)); } try { setStat("正在加载快捷方式..."); Li("reloading shortcuts index..."); - } catch(e0) {} + } catch(e0) { safeLog(null, 'e', "catch " + String(e0)); } try { state.allItems = buildShortcutItemsIndex(); var gg = groupItems(state.allItems); @@ -1060,11 +1060,11 @@ try { state.root.setVisibility(android.view.View.VISIBLE); } catch(eVis) {} state.groupOrder = ["__ALL__"]; Le("build index err=" + String(e1)); } - try { setupTabs(); } catch(eT0) {} - try { rebuildRenderList(); } catch(eT1) {} - try { clearGrid(); } catch(eT2) {} - try { appendBatch(); } catch(eT3) {} - try { startScrollPoll(); } catch(eT4) {} + try { setupTabs(); } catch(eT0) { safeLog(null, 'e', "catch " + String(eT0)); } + try { rebuildRenderList(); } catch(eT1) { safeLog(null, 'e', "catch " + String(eT1)); } + try { clearGrid(); } catch(eT2) { safeLog(null, 'e', "catch " + String(eT2)); } + try { appendBatch(); } catch(eT3) { safeLog(null, 'e', "catch " + String(eT3)); } + try { startScrollPoll(); } catch(eT4) { safeLog(null, 'e', "catch " + String(eT4)); } Li("shortcut picker reused items=" + String(state.allItems.length)); return; } @@ -1073,7 +1073,7 @@ try { state.root.setVisibility(android.view.View.VISIBLE); } catch(eVis) {} // build data setStat("正在加载快捷方式..."); Li("loading shortcuts index..."); - } catch(e0) {} + } catch(e0) { safeLog(null, 'e', "catch " + String(e0)); } try { state.allItems = buildShortcutItemsIndex(); @@ -1102,13 +1102,13 @@ try { state.root.setVisibility(android.view.View.VISIBLE); } catch(eVis) {} try { p.softInputMode = android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING | android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN; - } catch(eSIM0) {} + } catch(eSIM0) { safeLog(null, 'e', "catch " + String(eSIM0)); } // # 允许窗口覆盖到屏幕顶部区域(含状态栏区域),避免视觉上"不是贴顶" try { p.flags = p.flags | android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS; - } catch(eTop0) {} + } catch(eTop0) { safeLog(null, 'e', "catch " + String(eTop0)); } p.width = self.dp(340); p.height = self.dp(520); // # UI 修复:选择快捷方式页应贴近屏幕顶部显示(与"新增按钮页"的顶部布局一致),而不是居中 @@ -1128,7 +1128,7 @@ try { state.root.setVisibility(android.view.View.VISIBLE); } catch(eVis) {} // 允许输入法:搜索框要能聚焦 try { p.flags = p.flags & (~android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE); - } catch(eF) {} + } catch(eF) { safeLog(null, 'e', "catch " + String(eF)); } state.params = p; @@ -1161,15 +1161,15 @@ try { state.root.setVisibility(android.view.View.VISIBLE); } catch(eVis) {} var o = newOpts || {}; mode = (o.mode != null) ? String(o.mode) : mode; onPick = (typeof o.onPick === "function") ? o.onPick : onPick; - } catch(eOpt) {} + } catch(eOpt) { safeLog(null, 'e', "catch " + String(eOpt)); } // # 显示前先把隐藏标记清掉 - try { state.hidden = false; } catch(eH0) {} + try { state.hidden = false; } catch(eH0) { safeLog(null, 'e', "catch " + String(eH0)); } show(); }, hide: hide, destroy: destroy }; - try { self.__shortcutPickerSingleton = api; } catch(eSet) {} + try { self.__shortcutPickerSingleton = api; } catch(eSet) { safeLog(null, 'e', "catch " + String(eSet)); } api.show(opts); }; @@ -1196,7 +1196,7 @@ FloatBallAppWM.prototype.showIconPicker = function(opts) { self.__iconPickerSingleton.show(opts); return; } - } catch(eSingle) {} + } catch(eSingle) { safeLog(null, 'e', "catch " + String(eSingle)); } // # 获取图标列表 var allIcons = []; @@ -1207,7 +1207,7 @@ FloatBallAppWM.prototype.showIconPicker = function(opts) { } if (!allIcons || allIcons.length === 0) { self.toast("无法加载 ShortX 图标库"); - if (onDismiss) try { onDismiss(); } catch(eD) {} + if (onDismiss) try { onDismiss(); } catch(eD) { safeLog(null, 'e', "catch " + String(eD)); } return; } @@ -1237,8 +1237,8 @@ FloatBallAppWM.prototype.showIconPicker = function(opts) { totalPages: 1 }; - function Li(msg) { try { if (self.L) self.L.i("[iconPicker] " + msg); } catch(e) {} } - function Le(msg) { try { if (self.L) self.L.e("[iconPicker] " + msg); } catch(e) {} } + function Li(msg) { try { if (self.L) self.L.i("[iconPicker] " + msg); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } + function Le(msg) { try { if (self.L) self.L.e("[iconPicker] " + msg); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } // # 列数自适应计算 function computeColumns() { @@ -1292,14 +1292,14 @@ FloatBallAppWM.prototype.showIconPicker = function(opts) { // # 过滤 function filterIcons(q) { var qLower = ""; - try { qLower = String(q || "").toLowerCase(); } catch(e) {} + try { qLower = String(q || "").toLowerCase(); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } if (!qLower) return allIcons.slice(); var out = []; for (var i = 0; i < allIcons.length; i++) { var ic = allIcons[i]; if (!ic) continue; var name = ""; - try { name = String(ic.shortName || ic.name || "").toLowerCase(); } catch(e) {} + try { name = String(ic.shortName || ic.name || "").toLowerCase(); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } if (name.indexOf(qLower) >= 0) out.push(ic); } return out; @@ -1316,8 +1316,8 @@ FloatBallAppWM.prototype.showIconPicker = function(opts) { // 滚回顶部 try { if (state.scrollView) state.scrollView.scrollTo(0, 0); - } catch(eScroll) {} - } catch(e) {} + } catch(eScroll) { safeLog(null, 'e', "catch " + String(eScroll)); } + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } // # 更新统计/页码显示 @@ -1345,11 +1345,11 @@ FloatBallAppWM.prototype.showIconPicker = function(opts) { child.setEnabled(state.currentPage < state.totalPages - 1); child.setAlpha(state.currentPage < state.totalPages - 1 ? 1.0 : 0.35); } - } catch(eTag) {} + } catch(eTag) { safeLog(null, 'e', "catch " + String(eTag)); } } } - } catch(eBar) {} - } catch(e) {} + } catch(eBar) { safeLog(null, 'e', "catch " + String(eBar)); } + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } // # 构建网格(只渲染当前页) @@ -1397,8 +1397,8 @@ FloatBallAppWM.prototype.showIconPicker = function(opts) { try { var dr = self.resolveShortXDrawable(iconInfo.name); if (dr) iv.setImageDrawable(dr); - } catch(eIcon) {} - try { iv.setScaleType(android.widget.ImageView.ScaleType.CENTER_INSIDE); } catch(e) {} + } catch(eIcon) { safeLog(null, 'e', "catch " + String(eIcon)); } + try { iv.setScaleType(android.widget.ImageView.ScaleType.CENTER_INSIDE); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } var ivLp = new android.widget.LinearLayout.LayoutParams(self.dp(cellSizeDp), self.dp(cellSizeDp)); iv.setLayoutParams(ivLp); cell.addView(iv); @@ -1406,13 +1406,13 @@ FloatBallAppWM.prototype.showIconPicker = function(opts) { // 文字 var tv = new android.widget.TextView(context); var label = ""; - try { label = String(iconInfo.shortName || iconInfo.name || ""); } catch(e) {} + try { label = String(iconInfo.shortName || iconInfo.name || ""); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } if (label.length > 10) label = label.substring(0, 9) + "…"; tv.setText(label); tv.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, labelSizeSp); tv.setTextColor(textColor); tv.setGravity(android.view.Gravity.CENTER); - try { tv.setLines(1); tv.setEllipsize(android.text.TextUtils.TruncateAt.END); } catch(e) {} + try { tv.setLines(1); tv.setEllipsize(android.text.TextUtils.TruncateAt.END); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } var tvLp = new android.widget.LinearLayout.LayoutParams( android.widget.LinearLayout.LayoutParams.MATCH_PARENT, android.widget.LinearLayout.LayoutParams.WRAP_CONTENT @@ -1436,7 +1436,7 @@ FloatBallAppWM.prototype.showIconPicker = function(opts) { self.touchActivity(); if (onPick) onPick(iconInfo.name); hide(); - } catch(eClick) {} + } catch(eClick) { safeLog(null, 'e', "catch " + String(eClick)); } } })); @@ -1459,7 +1459,7 @@ FloatBallAppWM.prototype.showIconPicker = function(opts) { state.totalPages = Math.max(1, Math.ceil(state.filteredIcons.length / state.itemsPerPage)); state.currentPage = 0; buildGrid(); - } catch(e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } // # 隐藏 @@ -1475,12 +1475,12 @@ FloatBallAppWM.prototype.showIconPicker = function(opts) { var imm = context.getSystemService(Context.INPUT_METHOD_SERVICE); if (imm) imm.hideSoftInputFromWindow(state.etSearch.getWindowToken(), 0); } - } catch(eK) {} + } catch(eK) { safeLog(null, 'e', "catch " + String(eK)); } // 隐藏 View try { if (state.root) state.root.setVisibility(android.view.View.GONE); - } catch(eV) {} + } catch(eV) { safeLog(null, 'e', "catch " + String(eV)); } // 通知外层 try { @@ -1488,10 +1488,10 @@ FloatBallAppWM.prototype.showIconPicker = function(opts) { state.onDismissCalled = true; state.onDismiss(); } - } catch(eD) {} + } catch(eD) { safeLog(null, 'e', "catch " + String(eD)); } Li("icon picker hidden"); - } catch(eHide) {} + } catch(eHide) { safeLog(null, 'e', "catch " + String(eHide)); } } // # 销毁 @@ -1507,7 +1507,7 @@ FloatBallAppWM.prototype.showIconPicker = function(opts) { if (state.isAdded && state.root) { wm.removeView(state.root); } - } catch(eR) {} + } catch(eR) { safeLog(null, 'e', "catch " + String(eR)); } state.isAdded = false; state.root = null; @@ -1515,10 +1515,10 @@ FloatBallAppWM.prototype.showIconPicker = function(opts) { if (self.__currentIconSession === currentSession) { self.__currentIconSession = null; } - try { self.__iconPickerSingleton = null; } catch(eS) {} + try { self.__iconPickerSingleton = null; } catch(eS) { safeLog(null, 'e', "catch " + String(eS)); } Li("icon picker destroyed"); - } catch(eDes) {} + } catch(eDes) { safeLog(null, 'e', "catch " + String(eDes)); } } // # 显示(关键修复:正确处理隐藏后重新显示) @@ -1550,7 +1550,7 @@ FloatBallAppWM.prototype.showIconPicker = function(opts) { // 如果 root 存在但未添加(不应该发生),清掉重建 if (state.root && !state.isAdded) { - try { state.root = null; } catch(e) {} + try { state.root = null; } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } // ========== 新建面板 ========== @@ -1585,7 +1585,7 @@ FloatBallAppWM.prototype.showIconPicker = function(opts) { hide(); } } - } catch(eOut) {} + } catch(eOut) { safeLog(null, 'e', "catch " + String(eOut)); } } return false; } @@ -1598,7 +1598,7 @@ FloatBallAppWM.prototype.showIconPicker = function(opts) { bgDr.setColor(bgColor); bgDr.setCornerRadius(self.dp(16)); panel.setBackground(bgDr); - try { panel.setElevation(self.dp(8)); } catch(e) {} + try { panel.setElevation(self.dp(8)); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } panel.setPadding(self.dp(16), self.dp(12), self.dp(16), self.dp(12)); var panelLp = new android.widget.FrameLayout.LayoutParams(panelW, android.widget.FrameLayout.LayoutParams.WRAP_CONTENT); @@ -1656,7 +1656,7 @@ FloatBallAppWM.prototype.showIconPicker = function(opts) { var et = new android.widget.EditText(context); et.setHint("搜索图标名称..."); - try { et.setHintTextColor(subTextColor); } catch(e) {} + try { et.setHintTextColor(subTextColor); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } et.setTextColor(textColor); et.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 14); et.setBackground(null); @@ -1671,7 +1671,7 @@ FloatBallAppWM.prototype.showIconPicker = function(opts) { try { state.query = String(s || ""); rebuild(); - } catch(eTxt) {} + } catch(eTxt) { safeLog(null, 'e', "catch " + String(eTxt)); } } })); @@ -1689,7 +1689,7 @@ FloatBallAppWM.prototype.showIconPicker = function(opts) { et.setText(""); state.query = ""; rebuild(); - } catch(eClr) {} + } catch(eClr) { safeLog(null, 'e', "catch " + String(eClr)); } } })); searchBox.addView(btnClear); @@ -1698,8 +1698,8 @@ FloatBallAppWM.prototype.showIconPicker = function(opts) { // --- 滚动区域 --- var scroll = new android.widget.ScrollView(context); - try { scroll.setOverScrollMode(android.view.View.OVER_SCROLL_NEVER); } catch(e) {} - try { scroll.setVerticalScrollBarEnabled(false); } catch(e) {} + try { scroll.setOverScrollMode(android.view.View.OVER_SCROLL_NEVER); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } + try { scroll.setVerticalScrollBarEnabled(false); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } var grid = new android.widget.GridLayout(context); state.grid = grid; @@ -1754,11 +1754,11 @@ FloatBallAppWM.prototype.showIconPicker = function(opts) { self.dp(6) ); btn.setBackground(btnBg); - } catch(e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } btn.setClickable(true); btn.setOnClickListener(new android.view.View.OnClickListener({ onClick: function() { - try { self.touchActivity(); } catch(e) {} + try { self.touchActivity(); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } onClick(); } })); @@ -1806,7 +1806,7 @@ FloatBallAppWM.prototype.showIconPicker = function(opts) { } catch(eAdd) { Le("addView failed: " + String(eAdd)); self.toast("图标选择器打开失败"); - if (onDismiss) try { onDismiss(); } catch(eD) {} + if (onDismiss) try { onDismiss(); } catch(eD) { safeLog(null, 'e', "catch " + String(eD)); } return; } @@ -1825,7 +1825,7 @@ FloatBallAppWM.prototype.showIconPicker = function(opts) { .setDuration(180) .setInterpolator(new android.view.animation.AccelerateDecelerateInterpolator()) .start(); - } catch(eA) {} + } catch(eA) { safeLog(null, 'e', "catch " + String(eA)); } // 初始渲染(会计算分页) rebuild(); @@ -1842,14 +1842,14 @@ FloatBallAppWM.prototype.showIconPicker = function(opts) { onDismiss = (typeof o.onDismiss === "function") ? o.onDismiss : onDismiss; state.onDismiss = onDismiss; state.onDismissCalled = false; - } catch(eOpt) {} + } catch(eOpt) { safeLog(null, 'e', "catch " + String(eOpt)); } // 不在这里设置 state.hidden = false!让内部 show() 自己判断是隐藏重显还是新建 show(); }, hide: hide, destroy: destroy }; - try { self.__iconPickerSingleton = api; } catch(eSet) {} + try { self.__iconPickerSingleton = api; } catch(eSet) { safeLog(null, 'e', "catch " + String(eSet)); } api.show(opts); }; diff --git a/code/th_08_content.js b/code/th_08_content.js index 7dc6a58..8a3652e 100644 --- a/code/th_08_content.js +++ b/code/th_08_content.js @@ -114,7 +114,7 @@ FloatBallAppWM.prototype.contentQueryToText = function(uriStr, projection, selec out.err = String(e); return out; } finally { - try { if (cur) cur.close(); } catch (eC) {} + try { if (cur) cur.close(); } catch(eC) { safeLog(null, 'e', "catch " + String(eC)); } } }; diff --git a/code/th_09_animation.js b/code/th_09_animation.js index 94c5a0d..6746aa7 100644 --- a/code/th_09_animation.js +++ b/code/th_09_animation.js @@ -15,7 +15,7 @@ FloatBallAppWM.prototype.animateBallLayout = function(toX, toY, toW, durMs, endC // 0.7 的张力适中,不会过于夸张 va.setInterpolator(new android.view.animation.OvershootInterpolator(0.7)); } catch (eI) { - try { va.setInterpolator(new android.view.animation.DecelerateInterpolator()); } catch (eI2) {} + try { va.setInterpolator(new android.view.animation.DecelerateInterpolator()); } catch(eI2) { safeLog(null, 'e', "catch " + String(eI2)); } } var self = this; @@ -41,15 +41,18 @@ FloatBallAppWM.prototype.animateBallLayout = function(toX, toY, toW, durMs, endC self.state.wm.updateViewLayout(self.state.ballRoot, self.state.ballLp); }, true, self.L); } - } catch (e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } })); va.addListener(new android.animation.Animator.AnimatorListener({ onAnimationStart: function() {}, onAnimationRepeat: function() {}, - onAnimationCancel: function() {}, + onAnimationCancel: function() { + try { self.state.ballAnimator = null; } catch(e) { safeLog(null, 'e', "catch " + String(e)); } + }, onAnimationEnd: function() { + try { self.state.ballAnimator = null; } catch(e) { safeLog(null, 'e', "catch " + String(e)); } try { if (!self.state.closing && self.state.addedBall) { self.state.ballLp.x = toX; @@ -58,11 +61,12 @@ FloatBallAppWM.prototype.animateBallLayout = function(toX, toY, toW, durMs, endC self.state.wm.updateViewLayout(self.state.ballRoot, self.state.ballLp); self.savePos(self.state.ballLp.x, self.state.ballLp.y); } - } catch (e2) {} - try { if (endCb) endCb(); } catch (eCb) { try { if (self && self.L && self.L.e) self.L.e("animateBallLayout endCb err=" + String(eCb)); } catch (eLog) {} } + } catch(e2) { safeLog(null, 'e', "catch " + String(e2)); } + try { if (endCb) endCb(); } catch (eCb) { try { if (self && self.L && self.L.e) self.L.e("animateBallLayout endCb err=" + String(eCb)); } catch(eLog) { safeLog(null, 'e', "catch " + String(eLog)); } } } })); + this.state.ballAnimator = va; va.start(); } catch (e0) { try { @@ -71,8 +75,8 @@ FloatBallAppWM.prototype.animateBallLayout = function(toX, toY, toW, durMs, endC st.ballLp.width = toW; st.wm.updateViewLayout(st.ballRoot, st.ballLp); this.savePos(st.ballLp.x, st.ballLp.y); - } catch (e1) {} - try { if (endCb) endCb(); } catch (eCb2) { try { if (this && this.L && this.L.e) this.L.e("animateBallLayout endCb err=" + String(eCb2)); } catch (eLog2) {} } + } catch(e1) { safeLog(null, 'e', "catch " + String(e1)); } + try { if (endCb) endCb(); } catch (eCb2) { try { if (this && this.L && this.L.e) this.L.e("animateBallLayout endCb err=" + String(eCb2)); } catch(eLog2) { safeLog(null, 'e', "catch " + String(eLog2)); } } } }; @@ -80,7 +84,7 @@ FloatBallAppWM.prototype.playBounce = function(v) { if (!this.config.ENABLE_BOUNCE) return; if (!this.config.ENABLE_ANIMATIONS) return; - try { v.animate().cancel(); } catch (e0) {} + try { v.animate().cancel(); } catch(e0) { safeLog(null, 'e', "catch " + String(e0)); } var self = this; var i = 0; @@ -89,7 +93,7 @@ FloatBallAppWM.prototype.playBounce = function(v) { if (self.state.closing) return; if (i >= self.config.BOUNCE_TIMES) { - try { v.setScaleX(1); v.setScaleY(1); } catch (e2) {} + try { v.setScaleX(1); v.setScaleY(1); } catch(e2) { safeLog(null, 'e', "catch " + String(e2)); } return; } @@ -202,12 +206,12 @@ FloatBallAppWM.prototype.clearHeavyCaches = function(reason) { } this.state[cacheKey] = now; - try { this._iconLru = null; } catch (eLruClr) {} - try { this._shortcutIconFailTs = {}; } catch (e2) {} + try { this._iconLru = null; } catch(eLruClr) { safeLog(null, 'e', "catch " + String(eLruClr)); } + try { this._shortcutIconFailTs = {}; } catch(e2) { safeLog(null, 'e', "catch " + String(e2)); } // # Shortcuts 相关全局缓存(按钮编辑页/快捷方式选择器可能会创建) - try { if (typeof __scIconCache !== "undefined") __scIconCache = {}; } catch (e3) {} - try { if (typeof __scAppLabelCache !== "undefined") __scAppLabelCache = {}; } catch (e4) {} + try { if (typeof __scIconCache !== "undefined") __scIconCache = {}; } catch(e3) { safeLog(null, 'e', "catch " + String(e3)); } + try { if (typeof __scAppLabelCache !== "undefined") __scAppLabelCache = {}; } catch(e4) { safeLog(null, 'e', "catch " + String(e4)); } // # 记录一次清理日志(精简:只记录关键 reason,且 5秒防抖) var keyReasons = ["memory_pressure", "screen_changed", "close"]; @@ -216,7 +220,7 @@ FloatBallAppWM.prototype.clearHeavyCaches = function(reason) { if (isKeyReason && this.L && this.L.i) { this.L.i("clearHeavyCaches reason=" + String(reason)); } - } catch (e5) {} + } catch(e5) { safeLog(null, 'e', "catch " + String(e5)); } }; FloatBallAppWM.prototype._clearHeavyCachesIfAllHidden = function(reason) { @@ -225,7 +229,7 @@ FloatBallAppWM.prototype._clearHeavyCachesIfAllHidden = function(reason) { if (!this.state.addedPanel && !this.state.addedSettings && !this.state.addedViewer) { this.clearHeavyCaches(reason || "all_hidden"); } - } catch (e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } }; FloatBallAppWM.prototype.hideAllPanels = function() { @@ -287,7 +291,7 @@ FloatBallAppWM.prototype.showMask = function() { } else { mask.setAlpha(1); } - } catch(eAnim){} + } catch(eAnim) { safeLog(null, 'e', "catch " + String(eAnim)); } } catch (e1) { safeLog(this.L, 'e', "add mask fail err=" + String(e1)); @@ -322,7 +326,7 @@ FloatBallAppWM.prototype.snapToEdgeDocked = function(withAnim, forceSide) { this.state.dockSide = "left"; this.state.docked = true; - try { this.state.ballContent.setX(-hidden); } catch (eL) {} + try { this.state.ballContent.setX(-hidden); } catch(eL) { safeLog(null, 'e', "catch " + String(eL)); } if (withAnim) { this.animateBallLayout(0, targetY, targetW, this.config.DOCK_ANIM_MS, null); @@ -330,7 +334,7 @@ FloatBallAppWM.prototype.snapToEdgeDocked = function(withAnim, forceSide) { this.state.ballLp.x = 0; this.state.ballLp.y = targetY; this.state.ballLp.width = targetW; - try { this.state.wm.updateViewLayout(this.state.ballRoot, this.state.ballLp); } catch (eU1) {} + try { this.state.wm.updateViewLayout(this.state.ballRoot, this.state.ballLp); } catch(eU1) { safeLog(null, 'e', "catch " + String(eU1)); } this.savePos(this.state.ballLp.x, this.state.ballLp.y); } @@ -343,7 +347,7 @@ FloatBallAppWM.prototype.snapToEdgeDocked = function(withAnim, forceSide) { } else { this.state.ballContent.setAlpha(this.config.BALL_IDLE_ALPHA); } - } catch(eA) {} + } catch(eA) { safeLog(null, 'e', "catch " + String(eA)); } return; } @@ -351,7 +355,7 @@ FloatBallAppWM.prototype.snapToEdgeDocked = function(withAnim, forceSide) { this.state.dockSide = "right"; this.state.docked = true; - try { this.state.ballContent.setX(0); } catch (eR) {} + try { this.state.ballContent.setX(0); } catch(eR) { safeLog(null, 'e', "catch " + String(eR)); } var x2 = this.state.screen.w - visible; @@ -361,7 +365,7 @@ FloatBallAppWM.prototype.snapToEdgeDocked = function(withAnim, forceSide) { this.state.ballLp.x = x2; this.state.ballLp.y = targetY; this.state.ballLp.width = targetW; - try { this.state.wm.updateViewLayout(this.state.ballRoot, this.state.ballLp); } catch (eU2) {} + try { this.state.wm.updateViewLayout(this.state.ballRoot, this.state.ballLp); } catch(eU2) { safeLog(null, 'e', "catch " + String(eU2)); } this.savePos(this.state.ballLp.x, this.state.ballLp.y); } @@ -380,7 +384,7 @@ FloatBallAppWM.prototype.snapToEdgeDocked = function(withAnim, forceSide) { } else { this.state.ballContent.setAlpha(this.config.BALL_IDLE_ALPHA); } - } catch(eA) {} + } catch(eA) { safeLog(null, 'e', "catch " + String(eA)); } }; FloatBallAppWM.prototype.undockToFull = function(withAnim, endCb) { @@ -393,7 +397,7 @@ FloatBallAppWM.prototype.undockToFull = function(withAnim, endCb) { var targetW = ballSize; var targetY = this.clamp(this.state.ballLp.y, 0, this.state.screen.h - ballSize); - try { this.state.ballContent.setX(0); } catch (e0) {} + try { this.state.ballContent.setX(0); } catch(e0) { safeLog(null, 'e', "catch " + String(e0)); } if (this.state.dockSide === "left") { this.state.docked = false; @@ -404,7 +408,7 @@ FloatBallAppWM.prototype.undockToFull = function(withAnim, endCb) { this.state.ballLp.x = 0; this.state.ballLp.y = targetY; this.state.ballLp.width = targetW; - try { this.state.wm.updateViewLayout(this.state.ballRoot, this.state.ballLp); } catch (eU1) {} + try { this.state.wm.updateViewLayout(this.state.ballRoot, this.state.ballLp); } catch(eU1) { safeLog(null, 'e', "catch " + String(eU1)); } this.savePos(this.state.ballLp.x, this.state.ballLp.y); if (endCb) endCb(); } @@ -416,7 +420,7 @@ FloatBallAppWM.prototype.undockToFull = function(withAnim, endCb) { } else { this.state.ballContent.setAlpha(1.0); } - } catch(eA) {} + } catch(eA) { safeLog(null, 'e', "catch " + String(eA)); } safeLog(this.L, 'i', "undock from left"); return; @@ -432,7 +436,7 @@ FloatBallAppWM.prototype.undockToFull = function(withAnim, endCb) { this.state.ballLp.x = x; this.state.ballLp.y = targetY; this.state.ballLp.width = targetW; - try { this.state.wm.updateViewLayout(this.state.ballRoot, this.state.ballLp); } catch (eU2) {} + try { this.state.wm.updateViewLayout(this.state.ballRoot, this.state.ballLp); } catch(eU2) { safeLog(null, 'e', "catch " + String(eU2)); } this.savePos(this.state.ballLp.x, this.state.ballLp.y); if (endCb) endCb(); } @@ -444,7 +448,7 @@ FloatBallAppWM.prototype.undockToFull = function(withAnim, endCb) { } else { this.state.ballContent.setAlpha(1.0); } - } catch(eA) {} + } catch(eA) { safeLog(null, 'e', "catch " + String(eA)); } // # 日志精简:undock 事件改为 INFO 级别,且记录方向 var undockSide = this.state.dockSide || "right"; @@ -452,7 +456,7 @@ FloatBallAppWM.prototype.undockToFull = function(withAnim, endCb) { }; FloatBallAppWM.prototype.cancelDockTimer = function() { - try { if (this.state.idleDockRunnable && this.state.h) this.state.h.removeCallbacks(this.state.idleDockRunnable); } catch (e) {} + try { if (this.state.idleDockRunnable && this.state.h) this.state.h.removeCallbacks(this.state.idleDockRunnable); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } this.state.idleDockRunnable = null; }; @@ -518,7 +522,7 @@ FloatBallAppWM.prototype.guardClick = function(key, cooldownMs, fn) { return true; } catch (e0) { // 兜底:绝不让点击回调异常冒泡到 system_server - try { fn && fn(); } catch (e2) {} + try { fn && fn(); } catch(e2) { safeLog(null, 'e', "catch " + String(e2)); } return true; } }; @@ -576,22 +580,22 @@ FloatBallAppWM.prototype.onScreenChangedReflow = function() { if (this.state.dockSide === "left") { this.state.ballLp.x = 0; - try { this.state.ballContent.setX(-hidden); } catch (eL) {} + try { this.state.ballContent.setX(-hidden); } catch(eL) { safeLog(null, 'e', "catch " + String(eL)); } } else { this.state.ballLp.x = newW - visible; - try { this.state.ballContent.setX(0); } catch (eR) {} + try { this.state.ballContent.setX(0); } catch(eR) { safeLog(null, 'e', "catch " + String(eR)); } } // 重新进入闲置变暗逻辑(如果需要) - try { this.state.ballContent.setAlpha(this.config.BALL_IDLE_ALPHA); } catch(eA) {} + try { this.state.ballContent.setAlpha(this.config.BALL_IDLE_ALPHA); } catch(eA) { safeLog(null, 'e', "catch " + String(eA)); } } else { this.state.ballLp.x = mappedX; this.state.ballLp.y = mappedY; this.state.ballLp.width = ballSize; - try { this.state.ballContent.setX(0); } catch (e0) {} - try { this.state.ballContent.setAlpha(1.0); } catch(eA) {} + try { this.state.ballContent.setX(0); } catch(e0) { safeLog(null, 'e', "catch " + String(e0)); } + try { this.state.ballContent.setAlpha(1.0); } catch(eA) { safeLog(null, 'e', "catch " + String(eA)); } } - try { this.state.wm.updateViewLayout(this.state.ballRoot, this.state.ballLp); } catch (eU) {} + try { this.state.wm.updateViewLayout(this.state.ballRoot, this.state.ballLp); } catch(eU) { safeLog(null, 'e', "catch " + String(eU)); } this.savePos(this.state.ballLp.x, this.state.ballLp.y); safeLog(this.L, 'i', "screen reflow w=" + String(newW) + " h=" + String(newH) + " x=" + String(this.state.ballLp.x) + " y=" + String(this.state.ballLp.y)); @@ -642,7 +646,7 @@ FloatBallAppWM.prototype.setupDisplayMonitor = function() { } } })); - } catch (e0) {} + } catch(e0) { safeLog(null, 'e', "catch " + String(e0)); } } }); @@ -655,7 +659,7 @@ FloatBallAppWM.prototype.setupDisplayMonitor = function() { }; FloatBallAppWM.prototype.stopDisplayMonitor = function() { - try { if (this.state.dm && this.state.displayListener) this.state.dm.unregisterDisplayListener(this.state.displayListener); } catch (e) {} + try { if (this.state.dm && this.state.displayListener) this.state.dm.unregisterDisplayListener(this.state.displayListener); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } this.state.displayListener = null; this.state.dm = null; }; diff --git a/code/th_11_action.js b/code/th_11_action.js index 671d991..7d5eb4b 100644 --- a/code/th_11_action.js +++ b/code/th_11_action.js @@ -37,7 +37,7 @@ FloatBallAppWM.prototype.execButtonAction = function(btn, idx) { if (lines.length > 1) { content = lines.reverse().join("\n"); } - } catch(eRev) {} + } catch(eRev) { safeLog(null, 'e', "catch " + String(eRev)); } this.showViewerPanel("今日日志 (倒序)", content); return; @@ -80,7 +80,7 @@ try { } } catch (eA) { // # 兜底:某些 ROM/权限限制下 startActivityAsUser 可能抛异常,回退普通启动 - try { context.startActivity(it); } catch (eA2) {} + try { context.startActivity(it); } catch(eA2) { safeLog(null, 'e', "catch " + String(eA2)); } this.toast("启动失败"); safeLog(this.L, 'e', "start app fail pkg=" + pkg + " uid=" + String(launchUid) + " err=" + String(eA)); } @@ -98,7 +98,7 @@ return; try { var b64x = encodeBase64Utf8(cmdPlain); if (b64x && b64x.length > 0) cmdB64 = String(b64x); - } catch (eB64a) {} + } catch(eB64a) { safeLog(null, 'e', "catch " + String(eB64a)); } } // # 2) cmd_b64 非空但无法解码:把它当作"明文命令"重新编码(保证广播桥/Action 都能吃到正确命令) @@ -110,13 +110,13 @@ return; cmdPlain = String(cmdB64); cmdB64 = ""; } - } catch (eB64b) {} + } catch(eB64b) { safeLog(null, 'e', "catch " + String(eB64b)); } } if ((!cmdB64 || cmdB64.length === 0) && cmdPlain && cmdPlain.length > 0) { try { var b64y = encodeBase64Utf8(cmdPlain); if (b64y && b64y.length > 0) cmdB64 = String(b64y); - } catch (eB64c) {} + } catch(eB64c) { safeLog(null, 'e', "catch " + String(eB64c)); } } if (!cmdB64 || cmdB64.length === 0) { @@ -162,7 +162,7 @@ return; else if (typeof v === "boolean") it2.putExtra(String(k), !!v); else it2.putExtra(String(k), String(v)); } - } catch (eE) {} + } catch(eE) { safeLog(null, 'e', "catch " + String(eE)); } } // # 3) 对"Shell 广播桥"做额外兼容: @@ -189,7 +189,7 @@ return; cmdB64 = b64x; it2.putExtra(kCmdB64, String(cmdB64)); } - } catch (eC2) {} + } catch(eC2) { safeLog(null, 'e', "catch " + String(eC2)); } } // # 有 b64 但没明文:也补一份明文(便于外部规则验证;真正执行仍建议用 cmd_b64) @@ -200,7 +200,7 @@ return; cmdPlain = decoded; it2.putExtra("cmd", String(cmdPlain)); } - } catch (eC3) {} + } catch(eC3) { safeLog(null, 'e', "catch " + String(eC3)); } } // # root:广播桥接收端默认以 root 执行,强制传递 true @@ -211,7 +211,7 @@ return; } catch (eR0) { try { it2.putExtra(kRoot, true); - } catch (eR1) {} + } catch(eR1) { safeLog(null, 'e', "catch " + String(eR1)); } } @@ -230,21 +230,21 @@ return; } } } - } catch (eRB) {} + } catch(eRB) { safeLog(null, 'e', "catch " + String(eRB)); } // # from:标识来源(便于外部执行器做白名单/审计) try { if (!it2.hasExtra(kFrom)) it2.putExtra(kFrom, "ToolHub@system_server"); - } catch (eF0) { try { it2.putExtra(kFrom, "ToolHub@system_server"); } catch (eF1) {} } + } catch (eF0) { try { it2.putExtra(kFrom, "ToolHub@system_server"); } catch(eF1) { safeLog(null, 'e', "catch " + String(eF1)); } } if (this.L) { try { this.L.i("broadcast(shell_bridge) action=" + action + " cmd_len=" + String(cmdPlain ? cmdPlain.length : 0) + " cmd_b64_len=" + String(cmdB64 ? cmdB64.length : 0) + " root=" + String(it2.getBooleanExtra(kRoot, false))); - } catch (eLg) {} + } catch(eLg) { safeLog(null, 'e', "catch " + String(eLg)); } } } - } catch (eSB) {} + } catch(eSB) { safeLog(null, 'e', "catch " + String(eSB)); } try { context.sendBroadcast(it2); } catch (eB) { this.toast("广播失败"); safeLog(this.L, 'e', "broadcast fail action=" + action + " err=" + String(eB)); } return; @@ -271,7 +271,7 @@ return; var lu0 = parseInt(String(btn.launchUserId), 10); if (!isNaN(lu0)) uid = lu0; } - } catch(eLu0) {} + } catch(eLu0) { safeLog(null, 'e', "catch " + String(eLu0)); } if (!spkg) { this.toast("按钮#" + idx + " 缺少 pkg"); return; } if (!sid) { this.toast("按钮#" + idx + " 缺少 shortcutId"); return; } @@ -312,7 +312,7 @@ return; this.toast("未知 type=" + t); safeLog(this.L, 'w', "unknown btn type=" + t); } catch (eBtn) { - try { this.toast("按钮执行异常"); } catch (e0) {} + try { this.toast("按钮执行异常"); } catch(e0) { safeLog(null, 'e', "catch " + String(e0)); } safeLog(this.L, 'e', "execButtonAction crash idx=" + String(idx) + " err=" + String(eBtn)); } diff --git a/code/th_12_rebuild.js b/code/th_12_rebuild.js index 8fcd9ef..2d71d8d 100644 --- a/code/th_12_rebuild.js +++ b/code/th_12_rebuild.js @@ -63,7 +63,7 @@ FloatBallAppWM.prototype.rebuildBallForNewSize = function(keepPanels) { this.state.ballLp = lp; this.state.addedBall = true; } catch (eAdd) { - try { this.toast("重建悬浮球失败: " + String(eAdd)); } catch (eT) {} + try { this.toast("重建悬浮球失败: " + String(eAdd)); } catch(eT) { safeLog(null, 'e', "catch " + String(eT)); } safeLog(this.L, 'e', "rebuildBall add fail err=" + String(eAdd)); return false; } diff --git a/code/th_13_panel_ui.js b/code/th_13_panel_ui.js index 6972fdb..1de23fe 100644 --- a/code/th_13_panel_ui.js +++ b/code/th_13_panel_ui.js @@ -48,7 +48,7 @@ FloatBallAppWM.prototype.createSettingItemView = function(item, parent, needDivi var outValue = new android.util.TypedValue(); context.getTheme().resolveAttribute(android.R.attr.selectableItemBackground, outValue, true); row.setBackgroundResource(outValue.resourceId); - } catch(e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } row.setPadding(padH, padV, padH, padV); @@ -70,7 +70,7 @@ FloatBallAppWM.prototype.createSettingItemView = function(item, parent, needDivi row.addView(tv); var sw = new android.widget.Switch(context); - try { sw.setTextOn(""); sw.setTextOff(""); } catch (eT) {} + try { sw.setTextOn(""); sw.setTextOff(""); } catch(eT) { safeLog(null, 'e', "catch " + String(eT)); } // 优化开关颜色 try { @@ -86,7 +86,7 @@ FloatBallAppWM.prototype.createSettingItemView = function(item, parent, needDivi sw.setThumbTintList(thumbList); sw.setTrackTintList(trackList); - } catch(eColor) {} + } catch(eColor) { safeLog(null, 'e', "catch " + String(eColor)); } var cur = !!self.getPendingValue(item.key); sw.setChecked(cur); @@ -98,7 +98,7 @@ FloatBallAppWM.prototype.createSettingItemView = function(item, parent, needDivi self.touchActivity(); self.setPendingValue(item.key, !!checked); if (self.L) self.L.d("pending " + String(item.key) + "=" + String(!!checked)); - } catch (e0) {} + } catch(e0) { safeLog(null, 'e', "catch " + String(e0)); } } })); @@ -154,7 +154,7 @@ FloatBallAppWM.prototype.createSettingItemView = function(item, parent, needDivi try { sb.getThumb().setTint(primary); sb.getProgressDrawable().setTint(primary); - } catch(eColor) {} + } catch(eColor) { safeLog(null, 'e', "catch " + String(eColor)); } // 配置 SeekBar var min = (item.min !== undefined) ? Number(item.min) : 0; @@ -197,10 +197,10 @@ FloatBallAppWM.prototype.createSettingItemView = function(item, parent, needDivi if (fromUser) { self.setPendingValue(item.key, v); } - } catch (e1) {} + } catch(e1) { safeLog(null, 'e', "catch " + String(e1)); } }, - onStartTrackingTouch: function() { try { self.touchActivity(); } catch (e2) {} }, - onStopTrackingTouch: function() { try { self.touchActivity(); } catch (e3) {} } + onStartTrackingTouch: function() { try { self.touchActivity(); } catch(e2) { safeLog(null, 'e', "catch " + String(e2)); } }, + onStopTrackingTouch: function() { try { self.touchActivity(); } catch(e3) { safeLog(null, 'e', "catch " + String(e3)); } } })); row.addView(sb); @@ -239,7 +239,7 @@ FloatBallAppWM.prototype.createSettingItemView = function(item, parent, needDivi if (item.action === "open_btn_mgr") { self.showPanelAvoidBall("btn_editor"); } - } catch(e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } })); row.addView(btn); @@ -252,7 +252,7 @@ FloatBallAppWM.prototype.createSettingItemView = function(item, parent, needDivi if (item.action === "open_btn_mgr") { self.showPanelAvoidBall("btn_editor"); } - } catch(e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } })); @@ -289,7 +289,7 @@ FloatBallAppWM.prototype.createSettingItemView = function(item, parent, needDivi v.requestFocus(); var imm = context.getSystemService(android.content.Context.INPUT_METHOD_SERVICE); imm.showSoftInput(v, 0); - } catch(e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } })); @@ -300,7 +300,7 @@ FloatBallAppWM.prototype.createSettingItemView = function(item, parent, needDivi try { self.touchActivity(); self.setPendingValue(item.key, String(s)); - } catch (e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } })); @@ -338,7 +338,7 @@ FloatBallAppWM.prototype.createSettingItemView = function(item, parent, needDivi var states = [[android.R.attr.state_checked], [-android.R.attr.state_checked]]; var colors = [primary, secColor]; rb.setButtonTintList(new android.content.res.ColorStateList(states, colors)); - } catch(eC){} + } catch(eC) { safeLog(null, 'e', "catch " + String(eC)); } rb.setId(android.view.View.generateViewId ? android.view.View.generateViewId() : i); @@ -353,7 +353,7 @@ FloatBallAppWM.prototype.createSettingItemView = function(item, parent, needDivi try { self.touchActivity(); self.setPendingValue(item.key, String(opt.value)); - } catch(e){} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } } })); @@ -403,7 +403,7 @@ FloatBallAppWM.prototype.createSettingItemView = function(item, parent, needDivi } else { previewIv.setImageDrawable(null); } - } catch(ePreview0) {} + } catch(ePreview0) { safeLog(null, 'e', "catch " + String(ePreview0)); } } refreshBallShortXPreview(); @@ -435,7 +435,7 @@ FloatBallAppWM.prototype.createSettingItemView = function(item, parent, needDivi try { self.setPendingValue(item.key, ""); refreshBallShortXPreview(); - } catch(eClearBallIcon) {} + } catch(eClearBallIcon) { safeLog(null, 'e', "catch " + String(eClearBallIcon)); } }); iconRow.addView(btnClear); row.addView(iconRow); @@ -478,7 +478,7 @@ FloatBallAppWM.prototype.createSettingItemView = function(item, parent, needDivi colorDot.setBackground(self.ui.createRoundDrawable(0xFFCCCCCC | 0, self.dp(14))); } } catch(eDot0) { - try { colorDot.setBackground(self.ui.createRoundDrawable(0xFFCCCCCC | 0, self.dp(14))); } catch(eDot1) {} + try { colorDot.setBackground(self.ui.createRoundDrawable(0xFFCCCCCC | 0, self.dp(14))); } catch(eDot1) { safeLog(null, 'e', "catch " + String(eDot1)); } colorValueTv.setText("默认"); } } @@ -510,7 +510,7 @@ FloatBallAppWM.prototype.createSettingItemView = function(item, parent, needDivi try { self.setPendingValue(item.key, ""); refreshBallColorPreview(); - } catch(eClearBallColor) {} + } catch(eClearBallColor) { safeLog(null, 'e', "catch " + String(eClearBallColor)); } }); colorRow.addView(btnClearColor); row.addView(colorRow); diff --git a/code/th_14_panels.js b/code/th_14_panels.js index 30fc408..08f862d 100644 --- a/code/th_14_panels.js +++ b/code/th_14_panels.js @@ -76,14 +76,14 @@ FloatBallAppWM.prototype.buildSettingsPanelView = function() { previewBox.addView(tvPreview); var switchPreview = new android.widget.Switch(context); - try { switchPreview.setTextOn(""); switchPreview.setTextOff(""); } catch (eT) {} + try { switchPreview.setTextOn(""); switchPreview.setTextOff(""); } catch(eT) { safeLog(null, 'e', "catch " + String(eT)); } try { var states = [[android.R.attr.state_checked], [-android.R.attr.state_checked]]; var thumbColors = [C.accent, isDark ? (0xFF555555 | 0) : (0xFFCCCCCC | 0)]; var trackColors = [self.withAlpha(C.accent, 0.5), self.withAlpha(isDark ? (0xFF555555 | 0) : (0xFFCCCCCC | 0), 0.5)]; switchPreview.setThumbTintList(new android.content.res.ColorStateList(states, thumbColors)); switchPreview.setTrackTintList(new android.content.res.ColorStateList(states, trackColors)); - } catch(e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } switchPreview.setChecked(!!self.state.previewMode); switchPreview.setOnCheckedChangeListener(new android.widget.CompoundButton.OnCheckedChangeListener({ @@ -123,7 +123,7 @@ FloatBallAppWM.prototype.buildSettingsPanelView = function() { if (r && r.ok) self.toast("已确认并生效"); else self.toast("确认失败: " + (r && r.reason ? r.reason : (r && r.err ? r.err : "unknown"))); } catch (e0) { - try { self.toast("确认异常: " + String(e0)); } catch (eT) {} + try { self.toast("确认异常: " + String(e0)); } catch(eT) { safeLog(null, 'e', "catch " + String(eT)); } if (self.L) self.L.e("settings confirm err=" + String(e0)); } }); @@ -136,8 +136,8 @@ FloatBallAppWM.prototype.buildSettingsPanelView = function() { panel.addView(header); var scroll = new android.widget.ScrollView(context); - try { scroll.setOverScrollMode(android.view.View.OVER_SCROLL_NEVER); } catch (eOS) {} - try { scroll.setVerticalScrollBarEnabled(false); } catch (eSB) {} + try { scroll.setOverScrollMode(android.view.View.OVER_SCROLL_NEVER); } catch(eOS) { safeLog(null, 'e', "catch " + String(eOS)); } + try { scroll.setVerticalScrollBarEnabled(false); } catch(eSB) { safeLog(null, 'e', "catch " + String(eSB)); } var box = new android.widget.LinearLayout(context); box.setOrientation(android.widget.LinearLayout.VERTICAL); @@ -155,8 +155,8 @@ FloatBallAppWM.prototype.buildSettingsPanelView = function() { var c = new android.widget.LinearLayout(context); c.setOrientation(android.widget.LinearLayout.VERTICAL); c.setBackground(self.ui.createRoundDrawable(cardColor, self.dp(12))); - try { c.setElevation(self.dp(2)); } catch(e){} - try { c.setClipToOutline(true); } catch(e){} + try { c.setElevation(self.dp(2)); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } + try { c.setClipToOutline(true); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } var lp = new android.widget.LinearLayout.LayoutParams(android.widget.LinearLayout.LayoutParams.MATCH_PARENT, android.widget.LinearLayout.LayoutParams.WRAP_CONTENT); lp.setMargins(self.dp(2), self.dp(6), self.dp(2), self.dp(6)); c.setLayoutParams(lp); @@ -188,6 +188,157 @@ FloatBallAppWM.prototype.buildSettingsPanelView = function() { }; // =======================【按钮编辑面板】====================== + + function normalizeTintColorValue(v, allowEmpty) { + var s = (v === undefined || v === null) ? "" : String(v); + s = s.replace(/^\s+|\s+$/g, "").toUpperCase(); + if (!s) return allowEmpty ? "" : null; + if (s.charAt(0) !== "#") s = "#" + s; + if (/^#[0-9A-F]{6}$/.test(s)) return "#FF" + s.substring(1); + if (/^#[0-9A-F]{8}$/.test(s)) return s; + return null; + } + + function extractTintAlphaByte(hex) { + var n = normalizeTintColorValue(hex, false); + if (!n) return 255; + return parseInt(n.substring(1, 3), 16); + } + + function extractTintRgbHex(hex) { + var n = normalizeTintColorValue(hex, false); + if (!n) return "#FFFFFF"; + return "#" + n.substring(3); + } + + function buildArgbHex(alphaByte, rgbHex) { + var a = Number(alphaByte); + if (isNaN(a) || a < 0) a = 0; + if (a > 255) a = 255; + var rgb = String(rgbHex || "#FFFFFF").toUpperCase(); + if (rgb.charAt(0) !== "#") rgb = "#" + rgb; + if (!/^#[0-9A-F]{6}$/.test(rgb)) rgb = "#FFFFFF"; + var aHex = java.lang.Integer.toHexString(a & 255).toUpperCase(); + if (aHex.length < 2) aHex = "0" + aHex; + return "#" + aHex + rgb.substring(1); + } + +function __scStr(v) { try { return String(v == null ? "" : v); } catch(e) { return ""; } } + +function __scLower(v) { try { return __scStr(v).toLowerCase(); } catch(e) { return ""; } } + +function __scEnsureShortcutIconFile(item) { + // 这段代码的主要内容/用途:把 Launcher Shortcuts 的图标在"可见时"持久化为 PNG,后续按钮页直接读文件显示,避免桌面移除后图标退化/缺失。 + try { + if (!item) return ""; + var pkg = __scStr(item.pkg); + var sid = __scStr(item.shortcutId); + var uid = (item.userId != null) ? __scStr(item.userId) : "0"; + if (!pkg || !sid) return ""; + + var dir = String(APP_ROOT_DIR) + "/shortcut_icons"; + try { + var d = new java.io.File(dir); + if (!d.exists()) d.mkdirs(); + } catch(eMk) { safeLog(null, 'e', "catch " + String(eMk)); } + + // # 与主程序同名规则:pkg__sid__u{uid}.png + var fn = __scSanitizeFileName(pkg) + "__" + __scSanitizeFileName(sid) + "__u" + __scSanitizeFileName(uid) + ".png"; + var outPath = dir + "/" + fn; + + // # 已存在则直接复用 + try { + var f = new java.io.File(outPath); + if (f.exists() && f.isFile() && f.length() > 0) return outPath; + } catch(eEx) { safeLog(null, 'e', "catch " + String(eEx)); } + + // # 获取 Drawable(优先 shortcut icon,失败则回退 app icon) + var dr = null; + try { + if (__scLauncherApps && item.shortcutInfo) { + try { dr = __scLauncherApps.getShortcutIconDrawable(item.shortcutInfo, 0); } catch(eD0) { dr = null; } + } + } catch(eLA) { dr = null; } + if (!dr) { + try { + var pm = context.getPackageManager(); + dr = pm.getApplicationIcon(pkg); + } catch(eApp) { dr = null; } + } + if (!dr) return ""; + + // # Drawable -> Bitmap -> PNG + var bmp = null; + try { bmp = __scDrawableToBitmap(dr, 192); } catch(eBmp) { bmp = null; } + if (!bmp) return ""; + + var fos = null; + try { + fos = new java.io.FileOutputStream(outPath); + bmp.compress(android.graphics.Bitmap.CompressFormat.PNG, 100, fos); + try { fos.flush(); } catch(eFl) { safeLog(null, 'e', "catch " + String(eFl)); } + try { fos.close(); } catch(eCl) { safeLog(null, 'e', "catch " + String(eCl)); } + fos = null; + } catch(eW) { + try { if (fos) fos.close(); } catch(eCl2) { safeLog(null, 'e', "catch " + String(eCl2)); } + fos = null; + return ""; + } + + return outPath; + } catch(eAll) { + return ""; + } +} + +function __scSanitizeFileName(s) { + try { + var t = __scStr(s); + t = t.replace(/[^a-zA-Z0-9._-]+/g, "_"); + if (t.length > 120) t = t.substring(0, 120); + return t; + } catch(e) { return ""; } +} + +function __scDrawableToBitmap(drawable, targetPx) { + // 这段代码的主要内容/用途:把任意 Drawable 安全绘制成 Bitmap,便于持久化保存 PNG。 + try { + if (!drawable) return null; + + // BitmapDrawable 直接取 + try { + if (drawable instanceof android.graphics.drawable.BitmapDrawable) { + var b = drawable.getBitmap(); + if (b) return b; + } + } catch(eBD) { safeLog(null, 'e', "catch " + String(eBD)); } + + var w = 0, h = 0; + try { w = drawable.getIntrinsicWidth(); } catch(eW) { w = 0; } + try { h = drawable.getIntrinsicHeight(); } catch(eH) { h = 0; } + + if (w <= 0 || h <= 0) { + w = targetPx || 192; + h = targetPx || 192; + } + + // # 过大的直接缩到 targetPx 附近,避免 PNG 体积过大 + var maxSide = targetPx || 192; + var side = Math.max(w, h); + var scale = side > maxSide ? (maxSide / side) : 1.0; + var bw = Math.max(1, Math.round(w * scale)); + var bh = Math.max(1, Math.round(h * scale)); + + var bmp = android.graphics.Bitmap.createBitmap(bw, bh, android.graphics.Bitmap.Config.ARGB_8888); + var canvas = new android.graphics.Canvas(bmp); + drawable.setBounds(0, 0, bw, bh); + drawable.draw(canvas); + return bmp; + } catch(eAll) { + return null; + } +} + FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { var self = this; // # 状态管理:editingIndex (null=列表, -1=新增, >=0=编辑) @@ -233,7 +384,7 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { // # 列表滚动位置保持:刷新前记录当前 ScrollView 的 scrollY,避免操作后回到第一页 try { if (__btnEditorListScroll) self.state.btnEditorListScrollY = __btnEditorListScroll.getScrollY(); - } catch(eSY) {} + } catch(eSY) { safeLog(null, 'e', "catch " + String(eSY)); } // 标记为刷新操作,保留 tempButtons 状态 self.state.keepBtnEditorState = true; @@ -274,7 +425,7 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { // 列表区域 var scroll = new android.widget.ScrollView(context); __btnEditorListScroll = scroll; // # 列表滚动位置保持:让 refreshPanel 能拿到当前列表的滚动位置 - try { scroll.setVerticalScrollBarEnabled(false); } catch(e){} + try { scroll.setVerticalScrollBarEnabled(false); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } var list = new android.widget.LinearLayout(context); list.setOrientation(android.widget.LinearLayout.VERTICAL); list.setPadding(0, self.dp(2), 0, self.dp(2)); @@ -294,7 +445,7 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { // 使用稍微不同的背景色以突出卡片 var cardBgColor = isDark ? self.withAlpha(C.cardDark, 0.8) : self.withAlpha(C.cardLight, 0.8); card.setBackground(self.ui.createRoundDrawable(cardBgColor, self.dp(16))); - try { card.setElevation(self.dp(4)); } catch(e){} + try { card.setElevation(self.dp(4)); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } var cardLp = new android.widget.LinearLayout.LayoutParams(android.widget.LinearLayout.LayoutParams.MATCH_PARENT, android.widget.LinearLayout.LayoutParams.WRAP_CONTENT); cardLp.setMargins(self.dp(4), self.dp(4), self.dp(4), self.dp(4)); @@ -303,9 +454,9 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { // # 视觉提示:禁用项整体变淡,方便一眼区分 if (!__enabled) { - try { card.setAlpha(0.55); } catch(eA) {} + try { card.setAlpha(0.55); } catch(eA) { safeLog(null, 'e', "catch " + String(eA)); } } else { - try { card.setAlpha(1.0); } catch(eA2) {} + try { card.setAlpha(1.0); } catch(eA2) { safeLog(null, 'e', "catch " + String(eA2)); } } // 点击编辑 @@ -322,10 +473,10 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { try { var dr0 = self.resolveIconDrawable(btnCfg); if (dr0) iconIv.setImageDrawable(dr0); - } catch(eIcon0) {} - try { iconIv.setScaleType(android.widget.ImageView.ScaleType.CENTER_INSIDE); } catch(eScale){} + } catch(eIcon0) { safeLog(null, 'e', "catch " + String(eIcon0)); } + try { iconIv.setScaleType(android.widget.ImageView.ScaleType.CENTER_INSIDE); } catch(eScale) { safeLog(null, 'e', "catch " + String(eScale)); } var iconSizeDp = 24; - try { iconSizeDp = Number(self.config.PANEL_ICON_SIZE_DP || 24); } catch(eSz){} + try { iconSizeDp = Number(self.config.PANEL_ICON_SIZE_DP || 24); } catch(eSz) { safeLog(null, 'e', "catch " + String(eSz)); } // # 管理页行高更紧凑:限制 icon 尺寸,避免挤占文字区域 if (!iconSizeDp || iconSizeDp < 18) iconSizeDp = 24; if (iconSizeDp > 32) iconSizeDp = 32; @@ -391,7 +542,7 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { bg.setCornerRadius(self.dp(8)); // # 小一点圆角更紧凑 bg.setStroke(self.dp(1), self.withAlpha(subTextColor, 0.22)); tv.setBackground(bg); - } catch (eBg) {} + } catch(eBg) { safeLog(null, 'e', "catch " + String(eBg)); } if (!enabled) { tv.setEnabled(false); @@ -401,7 +552,7 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { tv.setTextColor(subTextColor); tv.setOnClickListener(new android.view.View.OnClickListener({ onClick: function() { - try { onClickFn(); } catch (eSort) {} + try { onClickFn(); } catch(eSort) { safeLog(null, 'e', "catch " + String(eSort)); } } })); } @@ -434,7 +585,7 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { ); lpD.leftMargin = self.dp(6); // # 横向排列:用左间距代替上间距 d.setLayoutParams(lpD); - } catch (eLp) {} + } catch(eLp) { safeLog(null, 'e', "catch " + String(eLp)); } sortBox.addView(d); actions.addView(sortBox); @@ -453,7 +604,7 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { tgBg.setCornerRadius(self.dp(8)); tgBg.setStroke(self.dp(1), self.withAlpha(subTextColor, 0.22)); btnToggle.setBackground(tgBg); - } catch (eTgBg) {} + } catch(eTgBg) { safeLog(null, 'e', "catch " + String(eTgBg)); } btnToggle.setTextColor(__enabled ? self.withAlpha(subTextColor, 0.9) : self.withAlpha(C.success, 0.9)); try { var lpTg = new android.widget.LinearLayout.LayoutParams( @@ -462,14 +613,14 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { ); lpTg.leftMargin = self.dp(6); btnToggle.setLayoutParams(lpTg); - } catch(eLpTg) {} + } catch(eLpTg) { safeLog(null, 'e', "catch " + String(eLpTg)); } btnToggle.setOnClickListener(new android.view.View.OnClickListener({ onClick: function() { try { btnCfg.enabled = (btnCfg.enabled === false) ? true : false; // # 立即持久化,避免面板关闭后丢失 ConfigManager.saveButtons(buttons); - } catch(eTg) {} + } catch(eTg) { safeLog(null, 'e', "catch " + String(eTg)); } refreshPanel(); } })); @@ -544,11 +695,11 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { if (_y > 0) { scroll.post(new java.lang.Runnable({ run: function() { - try { scroll.scrollTo(0, _y); } catch(eSY2) {} + try { scroll.scrollTo(0, _y); } catch(eSY2) { safeLog(null, 'e', "catch " + String(eSY2)); } } })); } - } catch(eSY3) {} + } catch(eSY3) { safeLog(null, 'e', "catch " + String(eSY3)); } // 底部按钮栏 var bottomBar = new android.widget.LinearLayout(context); @@ -590,7 +741,7 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { var targetBtn = (editIdx === -1) ? { type: "shell", title: "", cmd: "", iconResId: 0 } : JSON.parse(JSON.stringify(buttons[editIdx])); var scroll = new android.widget.ScrollView(context); - try { scroll.setVerticalScrollBarEnabled(false); } catch(e){} + try { scroll.setVerticalScrollBarEnabled(false); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } var form = new android.widget.LinearLayout(context); form.setOrientation(android.widget.LinearLayout.VERTICAL); form.setPadding(self.dp(4), self.dp(4), self.dp(4), self.dp(4)); @@ -736,39 +887,9 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { return "收起调色板"; } - function normalizeTintColorValue(v, allowEmpty) { - var s = (v === undefined || v === null) ? "" : String(v); - s = s.replace(/^\s+|\s+$/g, "").toUpperCase(); - if (!s) return allowEmpty ? "" : null; - if (s.charAt(0) !== "#") s = "#" + s; - if (/^#[0-9A-F]{6}$/.test(s)) return "#FF" + s.substring(1); - if (/^#[0-9A-F]{8}$/.test(s)) return s; - return null; - } - function extractTintAlphaByte(hex) { - var n = normalizeTintColorValue(hex, false); - if (!n) return 255; - return parseInt(n.substring(1, 3), 16); - } - function extractTintRgbHex(hex) { - var n = normalizeTintColorValue(hex, false); - if (!n) return "#FFFFFF"; - return "#" + n.substring(3); - } - function buildArgbHex(alphaByte, rgbHex) { - var a = Number(alphaByte); - if (isNaN(a) || a < 0) a = 0; - if (a > 255) a = 255; - var rgb = String(rgbHex || "#FFFFFF").toUpperCase(); - if (rgb.charAt(0) !== "#") rgb = "#" + rgb; - if (!/^#[0-9A-F]{6}$/.test(rgb)) rgb = "#FFFFFF"; - var aHex = java.lang.Integer.toHexString(a & 255).toUpperCase(); - if (aHex.length < 2) aHex = "0" + aHex; - return "#" + aHex + rgb.substring(1); - } function getThemeTintHex() { try { @@ -784,7 +905,7 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { expanded: !!tintPaletteState.expanded, recentColors: tintPaletteState.recentColors || [] }); - } catch(eTintSave0) {} + } catch(eTintSave0) { safeLog(null, 'e', "catch " + String(eTintSave0)); } } function pushRecentTintColor(hex) { @@ -809,12 +930,12 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { if (shortxPickerState.gridScroll) { shortxPickerState.gridScroll.post(new java.lang.Runnable({ run: function() { - try { shortxPickerState.gridScroll.fullScroll(android.view.View.FOCUS_UP); } catch(eScroll0) {} - try { shortxPickerState.gridScroll.scrollTo(0, 0); } catch(eScroll1) {} + try { shortxPickerState.gridScroll.fullScroll(android.view.View.FOCUS_UP); } catch(eScroll0) { safeLog(null, 'e', "catch " + String(eScroll0)); } + try { shortxPickerState.gridScroll.scrollTo(0, 0); } catch(eScroll1) { safeLog(null, 'e', "catch " + String(eScroll1)); } } })); } - } catch(eScrollWrap) {} + } catch(eScrollWrap) { safeLog(null, 'e', "catch " + String(eScrollWrap)); } } function resolveShortXPickerPageSize() { @@ -822,8 +943,8 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { var fallbackHeight = self.dp(520); var rawWidth = 0; var rawHeight = 0; - try { if (shortxPickerState.gridScroll) rawWidth = Number(shortxPickerState.gridScroll.getWidth() || 0); } catch(eW0) {} - try { if (shortxPickerState.gridScroll) rawHeight = Number(shortxPickerState.gridScroll.getHeight() || 0); } catch(eH0) {} + try { if (shortxPickerState.gridScroll) rawWidth = Number(shortxPickerState.gridScroll.getWidth() || 0); } catch(eW0) { safeLog(null, 'e', "catch " + String(eW0)); } + try { if (shortxPickerState.gridScroll) rawHeight = Number(shortxPickerState.gridScroll.getHeight() || 0); } catch(eH0) { safeLog(null, 'e', "catch " + String(eH0)); } if (rawWidth <= 0) rawWidth = fallbackWidth; if (rawHeight <= 0) rawHeight = fallbackHeight; var marginPx = self.dp(Number(shortxPickerState.cellMarginDp || 4)); @@ -855,7 +976,7 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { } try { if (shortxPickerState.toggleBtn) shortxPickerState.toggleBtn.setText(shortxPickerState.expanded ? getShortXPickerOpenedLabel() : getShortXPickerClosedLabel()); - } catch(eToggleTxt) {} + } catch(eToggleTxt) { safeLog(null, 'e', "catch " + String(eToggleTxt)); } if (shortxPickerState.expanded && doRender !== false) { resolveShortXPickerPageSize(); renderShortXIconGrid(); @@ -887,7 +1008,7 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { var shortxPreviewNameTv = new android.widget.TextView(context); shortxPreviewNameTv.setTextColor(textColor); shortxPreviewNameTv.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 12); - try { shortxPreviewNameTv.setSingleLine(true); shortxPreviewNameTv.setEllipsize(android.text.TextUtils.TruncateAt.END); } catch(eEL0) {} + try { shortxPreviewNameTv.setSingleLine(true); shortxPreviewNameTv.setEllipsize(android.text.TextUtils.TruncateAt.END); } catch(eEL0) { safeLog(null, 'e', "catch " + String(eEL0)); } shortxPreviewCard.addView(shortxPreviewNameTv, new android.widget.LinearLayout.LayoutParams(0, android.widget.LinearLayout.LayoutParams.WRAP_CONTENT, 1)); shortxPickerState.previewNameTv = shortxPreviewNameTv; @@ -903,10 +1024,10 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { onSelect: function(name) { currentShortXIconName = name; updateShortXIconPreview(); - try { if (shortxPickerState.toggleBtn) shortxPickerState.toggleBtn.setText(name || "\u9009\u62e9\u56fe\u6807"); } catch(e) {} + try { if (shortxPickerState.toggleBtn) shortxPickerState.toggleBtn.setText(name || "\u9009\u62e9\u56fe\u6807"); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } // # 选中 ShortX 图标后自动切换到 ShortX 图标模式,避免保存时走 file 分支导致颜色丢失 - try { rbIconShortX.setChecked(true); } catch(eRb) {} - try { updateIconInputs("shortx"); } catch(eUp) {} + try { rbIconShortX.setChecked(true); } catch(eRb) { safeLog(null, 'e', "catch " + String(eRb)); } + try { updateIconInputs("shortx"); } catch(eUp) { safeLog(null, 'e', "catch " + String(eUp)); } } }); }); @@ -965,7 +1086,7 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { var shortxSearchEt = new android.widget.EditText(context); shortxSearchEt.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 13); shortxSearchEt.setTextColor(textColor); - try { shortxSearchEt.setHintTextColor(subTextColor); } catch(eHintColor) {} + try { shortxSearchEt.setHintTextColor(subTextColor); } catch(eHintColor) { safeLog(null, 'e', "catch " + String(eHintColor)); } shortxSearchEt.setHint("搜索图标名,如 share / home / save"); shortxSearchEt.setSingleLine(true); shortxSearchEt.setPadding(self.dp(10), self.dp(8), self.dp(10), self.dp(8)); @@ -983,8 +1104,8 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { shortxPickerState.statusTv = shortxStatusTv; var shortxTabsScroll = new android.widget.HorizontalScrollView(context); - try { shortxTabsScroll.setHorizontalScrollBarEnabled(false); } catch(eTabSb) {} - try { shortxTabsScroll.setOverScrollMode(android.view.View.OVER_SCROLL_NEVER); } catch(eTabOs) {} + try { shortxTabsScroll.setHorizontalScrollBarEnabled(false); } catch(eTabSb) { safeLog(null, 'e', "catch " + String(eTabSb)); } + try { shortxTabsScroll.setOverScrollMode(android.view.View.OVER_SCROLL_NEVER); } catch(eTabOs) { safeLog(null, 'e', "catch " + String(eTabOs)); } var shortxTabsLp = new android.widget.LinearLayout.LayoutParams(android.widget.LinearLayout.LayoutParams.MATCH_PARENT, android.widget.LinearLayout.LayoutParams.WRAP_CONTENT); shortxTabsLp.setMargins(self.dp(8), 0, self.dp(8), self.dp(6)); shortxPickerWrap.addView(shortxTabsScroll, shortxTabsLp); @@ -1031,7 +1152,7 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { try { btn.setTextColor(active ? android.graphics.Color.WHITE : textColor); btn.setBackground(self.ui.createRoundDrawable(active ? C.primary : self.withAlpha(cardColor, 0.96), self.dp(16))); - } catch(eTabStyle) {} + } catch(eTabStyle) { safeLog(null, 'e', "catch " + String(eTabStyle)); } } } @@ -1084,15 +1205,15 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { applyShortXTabStyles(); var shortxGridScroll = new android.widget.ScrollView(context); - try { shortxGridScroll.setVerticalScrollBarEnabled(false); } catch(eSG0) {} - try { shortxGridScroll.setOverScrollMode(android.view.View.OVER_SCROLL_NEVER); } catch(eSG1) {} + try { shortxGridScroll.setVerticalScrollBarEnabled(false); } catch(eSG0) { safeLog(null, 'e', "catch " + String(eSG0)); } + try { shortxGridScroll.setOverScrollMode(android.view.View.OVER_SCROLL_NEVER); } catch(eSG1) { safeLog(null, 'e', "catch " + String(eSG1)); } var shortxGridScrollLp = new android.widget.LinearLayout.LayoutParams(android.widget.LinearLayout.LayoutParams.MATCH_PARENT, self.dp(520)); shortxGridScrollLp.setMargins(self.dp(8), 0, self.dp(8), self.dp(8)); shortxPickerWrap.addView(shortxGridScroll, shortxGridScrollLp); shortxPickerState.gridScroll = shortxGridScroll; var shortxGrid = new android.widget.GridLayout(context); - try { shortxGrid.setColumnCount(Math.max(1, Number(shortxPickerState.pageCols || 1))); } catch(eGC0) {} + try { shortxGrid.setColumnCount(Math.max(1, Number(shortxPickerState.pageCols || 1))); } catch(eGC0) { safeLog(null, 'e', "catch " + String(eGC0)); } shortxGrid.setPadding(self.dp(4), self.dp(4), self.dp(4), self.dp(4)); shortxGridScroll.addView(shortxGrid); shortxPickerState.grid = shortxGrid; @@ -1108,10 +1229,10 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { var drPreview = normalizedShort ? self.resolveShortXDrawable(normalizedShort, tintHex) : null; if (drPreview) { shortxPickerState.previewIv.setImageDrawable(drPreview); - try { shortxPickerState.previewIv.setAlpha(1.0); } catch(eA1) {} + try { shortxPickerState.previewIv.setAlpha(1.0); } catch(eA1) { safeLog(null, 'e', "catch " + String(eA1)); } } else { shortxPickerState.previewIv.setImageDrawable(null); - try { shortxPickerState.previewIv.setAlpha(0.35); } catch(eA2) {} + try { shortxPickerState.previewIv.setAlpha(0.35); } catch(eA2) { safeLog(null, 'e', "catch " + String(eA2)); } } } } catch(ePreview) { @@ -1123,11 +1244,11 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { try { if (!shortxPickerState.grid) return; shortxPickerState.grid.removeAllViews(); - try { shortxPickerState.grid.setColumnCount(Math.max(1, Number(shortxPickerState.pageCols || 1))); } catch(eColSet) {} + try { shortxPickerState.grid.setColumnCount(Math.max(1, Number(shortxPickerState.pageCols || 1))); } catch(eColSet) { safeLog(null, 'e', "catch " + String(eColSet)); } var icons = self.getShortXIconCatalog(); shortxPickerState.iconList = icons; var query = ""; - try { query = String(shortxPickerState.searchEt.getText() || "").replace(/^\s+|\s+$/g, "").toLowerCase(); } catch(eQ0) {} + try { query = String(shortxPickerState.searchEt.getText() || "").replace(/^\s+|\s+$/g, "").toLowerCase(); } catch(eQ0) { safeLog(null, 'e', "catch " + String(eQ0)); } shortxPickerState.lastQuery = query; var filtered = []; var totalMatch = 0; @@ -1164,8 +1285,8 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { if (shortxPickerState.pageInfoTv) { shortxPickerState.pageInfoTv.setText((filtered.length > 0 ? (shortxPickerState.currentPage + 1) : 0) + " / " + totalPages + " · " + filtered.length + "项 · " + shortxPickerState.pageCols + "列 · 每页" + pageSize + "个"); } - try { shortxPickerState.prevBtn.setEnabled(shortxPickerState.currentPage > 0); } catch(ePrev) {} - try { shortxPickerState.nextBtn.setEnabled(shortxPickerState.currentPage < totalPages - 1); } catch(eNext) {} + try { shortxPickerState.prevBtn.setEnabled(shortxPickerState.currentPage > 0); } catch(ePrev) { safeLog(null, 'e', "catch " + String(ePrev)); } + try { shortxPickerState.nextBtn.setEnabled(shortxPickerState.currentPage < totalPages - 1); } catch(eNext) { safeLog(null, 'e', "catch " + String(eNext)); } applyShortXTabStyles(); var tintHex = currentShortXIconTint || ""; var selectedShort = currentShortXIconName ? self.normalizeShortXIconName(currentShortXIconName, false) : ""; @@ -1190,7 +1311,7 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { try { var drIcon = self.resolveShortXDrawable(entry.name, tintHex); if (drIcon) iv.setImageDrawable(drIcon); - } catch(eIconDraw) {} + } catch(eIconDraw) { safeLog(null, 'e', "catch " + String(eIconDraw)); } cell.addView(iv); var tv = new android.widget.TextView(context); @@ -1198,7 +1319,7 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { tv.setTextColor(isSelected ? C.primary : textColor); tv.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 10); tv.setGravity(android.view.Gravity.CENTER); - try { tv.setLines(2); tv.setEllipsize(android.text.TextUtils.TruncateAt.END); } catch(eLines0) {} + try { tv.setLines(2); tv.setEllipsize(android.text.TextUtils.TruncateAt.END); } catch(eLines0) { safeLog(null, 'e', "catch " + String(eLines0)); } cell.addView(tv, new android.widget.LinearLayout.LayoutParams(android.widget.LinearLayout.LayoutParams.MATCH_PARENT, android.widget.LinearLayout.LayoutParams.WRAP_CONTENT)); cell.setClickable(true); @@ -1215,7 +1336,7 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { })(result[i]); } } catch(eRenderIcons) { - try { if (shortxPickerState.statusTv) shortxPickerState.statusTv.setText("图标库加载失败: " + eRenderIcons); } catch(eStatus0) {} + try { if (shortxPickerState.statusTv) shortxPickerState.statusTv.setText("图标库加载失败: " + eRenderIcons); } catch(eStatus0) { safeLog(null, 'e', "catch " + String(eStatus0)); } } } @@ -1229,7 +1350,7 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { beforeTextChanged: function(s, st, c, a) {}, onTextChanged: function(s, st, b, c) {} })); - } catch(eTwIcon0) {} + } catch(eTwIcon0) { safeLog(null, 'e', "catch " + String(eTwIcon0)); } try { shortxGridScroll.getViewTreeObserver().addOnGlobalLayoutListener(new android.view.ViewTreeObserver.OnGlobalLayoutListener({ @@ -1245,7 +1366,7 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { } } })); - } catch(eGridLayoutWatch) {} + } catch(eGridLayoutWatch) { safeLog(null, 'e', "catch " + String(eGridLayoutWatch)); } // # ShortX 图标颜色(留空跟随主题) var defaultTint = targetBtn.iconTint ? String(targetBtn.iconTint) : ""; @@ -1258,14 +1379,14 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { function updateTintPaletteToggleText() { try { if (tintPaletteState.toggleBtn) tintPaletteState.toggleBtn.setText(tintPaletteState.expanded ? getTintPaletteOpenedLabel() : getTintPaletteClosedLabel()); - } catch(eTintToggle0) {} + } catch(eTintToggle0) { safeLog(null, 'e', "catch " + String(eTintToggle0)); } } function setTintPaletteExpanded(expanded) { tintPaletteState.expanded = !!expanded; try { if (tintPaletteState.body) tintPaletteState.body.setVisibility(tintPaletteState.expanded ? android.view.View.VISIBLE : android.view.View.GONE); - } catch(eTintBody0) {} + } catch(eTintBody0) { safeLog(null, 'e', "catch " + String(eTintBody0)); } updateTintPaletteToggleText(); saveTintPaletteState(); } @@ -1273,7 +1394,7 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { function setTintSeekProgress(progress) { try { if (tintPaletteState.alphaSeek) tintPaletteState.alphaSeek.setProgress(Number(progress || 0)); - } catch(eTintSeek0) {} + } catch(eTintSeek0) { safeLog(null, 'e', "catch " + String(eTintSeek0)); } } function setRgbSeekProgress(which, value) { @@ -1284,7 +1405,7 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { if (which === "r" && tintPaletteState.redSeek) tintPaletteState.redSeek.setProgress(v); if (which === "g" && tintPaletteState.greenSeek) tintPaletteState.greenSeek.setProgress(v); if (which === "b" && tintPaletteState.blueSeek) tintPaletteState.blueSeek.setProgress(v); - } catch(eTintRgbSeek0) {} + } catch(eTintRgbSeek0) { safeLog(null, 'e', "catch " + String(eTintRgbSeek0)); } } function updateTintAlphaLabel(alphaByte) { @@ -1294,7 +1415,7 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { var pct = Math.round((a / 255) * 100); try { if (tintPaletteState.alphaValueTv) tintPaletteState.alphaValueTv.setText("透明度 " + pct + "%(" + a + "/255)"); - } catch(eTintAlpha0) {} + } catch(eTintAlpha0) { safeLog(null, 'e', "catch " + String(eTintAlpha0)); } } function updateRgbValueLabel(which, value) { @@ -1305,7 +1426,7 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { if (which === "r" && tintPaletteState.redValueTv) tintPaletteState.redValueTv.setText("R " + v); if (which === "g" && tintPaletteState.greenValueTv) tintPaletteState.greenValueTv.setText("G " + v); if (which === "b" && tintPaletteState.blueValueTv) tintPaletteState.blueValueTv.setText("B " + v); - } catch(eTintRgbLbl0) {} + } catch(eTintRgbLbl0) { safeLog(null, 'e', "catch " + String(eTintRgbLbl0)); } } function updateRgbLabelsFromHex(rgbHex) { @@ -1323,7 +1444,7 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { try { colorInt = android.graphics.Color.parseColor(effectiveHex); } catch(eColor0) { colorInt = C.primary; } try { if (tintPaletteState.previewDot) tintPaletteState.previewDot.setBackground(self.ui.createRoundDrawable(colorInt, self.dp(12))); - } catch(eTintPrevDot0) {} + } catch(eTintPrevDot0) { safeLog(null, 'e', "catch " + String(eTintPrevDot0)); } var msg = ""; if (invalidRaw) { msg = "当前:" + invalidRaw + "(格式无效)"; @@ -1335,12 +1456,12 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { } try { if (tintPaletteState.previewTextTv) tintPaletteState.previewTextTv.setText(msg); - } catch(eTintPrevTv0) {} + } catch(eTintPrevTv0) { safeLog(null, 'e', "catch " + String(eTintPrevTv0)); } } function syncTintUiFromInput(pushRecent) { var raw = ""; - try { raw = String(inputShortXIconTint.getValue() || "").replace(/^\s+|\s+$/g, ""); } catch(eTintRaw0) {} + try { raw = String(inputShortXIconTint.getValue() || "").replace(/^\s+|\s+$/g, ""); } catch(eTintRaw0) { safeLog(null, 'e', "catch " + String(eTintRaw0)); } var normalized = normalizeTintColorValue(raw, true); if (raw && !normalized) { currentShortXIconTint = raw; @@ -1373,7 +1494,7 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { try { tintPaletteState.syncing = true; inputShortXIconTint.input.setText(currentShortXIconTint); - } catch(eSetTint0) {} + } catch(eSetTint0) { safeLog(null, 'e', "catch " + String(eSetTint0)); } tintPaletteState.syncing = false; syncTintUiFromInput(!!pushRecent); } @@ -1388,30 +1509,30 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { tintPaletteState.syncing = true; if (inputShortXIconTint && inputShortXIconTint.input) { inputShortXIconTint.input.setText(safeColor); - try { inputShortXIconTint.input.setSelection(String(safeColor).length); } catch(eSelTint0) {} - try { inputShortXIconTint.input.invalidate(); } catch(eInvTint0) {} - try { inputShortXIconTint.input.requestLayout(); } catch(eReqTint0) {} + try { inputShortXIconTint.input.setSelection(String(safeColor).length); } catch(eSelTint0) { safeLog(null, 'e', "catch " + String(eSelTint0)); } + try { inputShortXIconTint.input.invalidate(); } catch(eInvTint0) { safeLog(null, 'e', "catch " + String(eInvTint0)); } + try { inputShortXIconTint.input.requestLayout(); } catch(eReqTint0) { safeLog(null, 'e', "catch " + String(eReqTint0)); } } } catch(eSetTint1) { safeLog(self.L, 'e', "applyTintSelectionFromPopup setText err=" + String(eSetTint1)); } tintPaletteState.syncing = false; try { syncTintUiFromInput(!!safeColor); } catch(eSyncTint1) { safeLog(self.L, 'e', "applyTintSelectionFromPopup sync err=" + String(eSyncTint1)); } - try { if (rbIconShortX) rbIconShortX.setChecked(true); } catch(eRbTint0) {} - try { updateIconInputs("shortx"); } catch(eIconInputTint0) {} - try { if (tintPaletteState.toggleBtn) tintPaletteState.toggleBtn.setText(safeColor || "\u9009\u62e9\u989c\u8272"); } catch(eTintPopupBtn0) {} + try { if (rbIconShortX) rbIconShortX.setChecked(true); } catch(eRbTint0) { safeLog(null, 'e', "catch " + String(eRbTint0)); } + try { updateIconInputs("shortx"); } catch(eIconInputTint0) { safeLog(null, 'e', "catch " + String(eIconInputTint0)); } + try { if (tintPaletteState.toggleBtn) tintPaletteState.toggleBtn.setText(safeColor || "\u9009\u62e9\u989c\u8272"); } catch(eTintPopupBtn0) { safeLog(null, 'e', "catch " + String(eTintPopupBtn0)); } try { if (shortxPickerState.previewIv) { var normalizedShort = currentShortXIconName ? self.normalizeShortXIconName(currentShortXIconName, false) : ""; var drDirect = normalizedShort ? self.resolveShortXDrawable(normalizedShort, currentShortXIconTint || "") : null; shortxPickerState.previewIv.setImageDrawable(drDirect); - try { shortxPickerState.previewIv.invalidate(); } catch(ePrevInv0) {} + try { shortxPickerState.previewIv.invalidate(); } catch(ePrevInv0) { safeLog(null, 'e', "catch " + String(ePrevInv0)); } } } catch(eTintDirect0) { safeLog(self.L, 'e', "applyTintSelectionFromPopup directPreview err=" + String(eTintDirect0)); } try { updateShortXIconPreview(); } catch(eTintPopupPreview0) { safeLog(self.L, 'e', "applyTintSelectionFromPopup preview err=" + String(eTintPopupPreview0)); } - try { if (shortxPickerState.expanded) renderShortXIconGrid(); } catch(eTintGrid0) {} + try { if (shortxPickerState.expanded) renderShortXIconGrid(); } catch(eTintGrid0) { safeLog(null, 'e', "catch " + String(eTintGrid0)); } safeLog(self.L, 'i', "applyTintSelectionFromPopup color=" + String(safeColor) + ", icon=" + String(currentShortXIconName || "")); } @@ -1451,7 +1572,7 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { if (cellWidthPx && Number(cellWidthPx) > 0) lp.width = Number(cellWidthPx); lp.setMargins(self.dp(4), self.dp(4), self.dp(4), self.dp(4)); wrap.setLayoutParams(lp); - try { wrap.setBackground(self.ui.createRoundDrawable(self.withAlpha(cardColor, 0.96), self.dp(10))); } catch(eTintSwBg0) {} + try { wrap.setBackground(self.ui.createRoundDrawable(self.withAlpha(cardColor, 0.96), self.dp(10))); } catch(eTintSwBg0) { safeLog(null, 'e', "catch " + String(eTintSwBg0)); } var effectiveHex = isFollowTheme ? getThemeTintHex() : normalizeTintColorValue(hexValue, false); var dot = new android.view.View(context); @@ -1460,7 +1581,7 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { try { var dotColorInt = effectiveHex ? android.graphics.Color.parseColor(effectiveHex) : self.withAlpha(C.primary, 0.18); dot.setBackground(self.ui.createRoundDrawable(dotColorInt, self.dp(12))); - } catch(eTintSwDot0) {} + } catch(eTintSwDot0) { safeLog(null, 'e', "catch " + String(eTintSwDot0)); } wrap.addView(dot, dotLp); var tv = new android.widget.TextView(context); @@ -1489,14 +1610,14 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { function renderRecentTintGrid() { if (!tintPaletteState.recentGrid) return; - try { tintPaletteState.recentGrid.removeAllViews(); } catch(eTintRecent0) {} + try { tintPaletteState.recentGrid.removeAllViews(); } catch(eTintRecent0) { safeLog(null, 'e', "catch " + String(eTintRecent0)); } var list = tintPaletteState.recentColors || []; var i; if (!list.length) { - try { if (tintPaletteState.recentEmptyTv) tintPaletteState.recentEmptyTv.setVisibility(android.view.View.VISIBLE); } catch(eTintRecent1) {} + try { if (tintPaletteState.recentEmptyTv) tintPaletteState.recentEmptyTv.setVisibility(android.view.View.VISIBLE); } catch(eTintRecent1) { safeLog(null, 'e', "catch " + String(eTintRecent1)); } return; } - try { if (tintPaletteState.recentEmptyTv) tintPaletteState.recentEmptyTv.setVisibility(android.view.View.GONE); } catch(eTintRecent2) {} + try { if (tintPaletteState.recentEmptyTv) tintPaletteState.recentEmptyTv.setVisibility(android.view.View.GONE); } catch(eTintRecent2) { safeLog(null, 'e', "catch " + String(eTintRecent2)); } for (i = 0; i < list.length && i < 5; i++) { tintPaletteState.recentGrid.addView(createTintSwatchCell("最近" + (i + 1), list[i], false, 0)); } @@ -1559,7 +1680,7 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { tintPreviewCard.setOrientation(android.widget.LinearLayout.HORIZONTAL); tintPreviewCard.setGravity(android.view.Gravity.CENTER_VERTICAL); tintPreviewCard.setPadding(self.dp(10), self.dp(8), self.dp(10), self.dp(8)); - try { tintPreviewCard.setBackground(self.ui.createRoundDrawable(self.withAlpha(C.primary, 0.08), self.dp(12))); } catch(eTintPrevCard0) {} + try { tintPreviewCard.setBackground(self.ui.createRoundDrawable(self.withAlpha(C.primary, 0.08), self.dp(12))); } catch(eTintPrevCard0) { safeLog(null, 'e', "catch " + String(eTintPrevCard0)); } tintPaletteBody.addView(tintPreviewCard); var tintPalettePreviewDot = new android.view.View(context); @@ -1594,7 +1715,7 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { tintPaletteState.alphaValueTv = tintAlphaValue; var tintSeek = new android.widget.SeekBar(context); - try { tintSeek.setMax(255); } catch(eTintSeekMax0) {} + try { tintSeek.setMax(255); } catch(eTintSeekMax0) { safeLog(null, 'e', "catch " + String(eTintSeekMax0)); } var tintSeekLp = new android.widget.LinearLayout.LayoutParams(android.widget.LinearLayout.LayoutParams.MATCH_PARENT, android.widget.LinearLayout.LayoutParams.WRAP_CONTENT); tintSeekLp.setMargins(0, 0, 0, self.dp(8)); tintPaletteBody.addView(tintSeek, tintSeekLp); @@ -1613,7 +1734,7 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { applyTintFromCurrentBase(true); } })); - } catch(eTintSeekListener0) {} + } catch(eTintSeekListener0) { safeLog(null, 'e', "catch " + String(eTintSeekListener0)); } function createRgbControlRow(label, key, accentHex) { var row = new android.widget.LinearLayout(context); @@ -1635,7 +1756,7 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { row.addView(valueTv); var seek = new android.widget.SeekBar(context); - try { seek.setMax(255); } catch(eTintRgbMax0) {} + try { seek.setMax(255); } catch(eTintRgbMax0) { safeLog(null, 'e', "catch " + String(eTintRgbMax0)); } row.addView(seek, new android.widget.LinearLayout.LayoutParams(0, android.widget.LinearLayout.LayoutParams.WRAP_CONTENT, 1)); if (key === "r") { tintPaletteState.redSeek = seek; tintPaletteState.redValueTv = valueTv; } @@ -1657,7 +1778,7 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { applyTintFromRgbSeekbars(true); } })); - } catch(eTintRgbListener0) {} + } catch(eTintRgbListener0) { safeLog(null, 'e', "catch " + String(eTintRgbListener0)); } return row; } @@ -1687,7 +1808,7 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { tintPaletteState.recentEmptyTv = tintRecentEmptyTv; var tintRecentGrid = new android.widget.GridLayout(context); - try { tintRecentGrid.setColumnCount(5); } catch(eTintRecentCols0) {} + try { tintRecentGrid.setColumnCount(5); } catch(eTintRecentCols0) { safeLog(null, 'e', "catch " + String(eTintRecentCols0)); } tintPaletteBody.addView(tintRecentGrid); tintPaletteState.recentGrid = tintRecentGrid; @@ -1699,15 +1820,15 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { tintPaletteBody.addView(tintCommonTitle); var tintCommonGrid = new android.widget.GridLayout(context); - try { tintCommonGrid.setColumnCount(1); } catch(eTintCommonCols0) {} + try { tintCommonGrid.setColumnCount(1); } catch(eTintCommonCols0) { safeLog(null, 'e', "catch " + String(eTintCommonCols0)); } tintPaletteBody.addView(tintCommonGrid); tintPaletteState.commonGrid = tintCommonGrid; function resolveTintCommonGridLayout() { var rawWidth = 0; - try { if (tintPaletteState.commonGrid) rawWidth = Number(tintPaletteState.commonGrid.getWidth() || 0); } catch(eTintCommonW0) {} + try { if (tintPaletteState.commonGrid) rawWidth = Number(tintPaletteState.commonGrid.getWidth() || 0); } catch(eTintCommonW0) { safeLog(null, 'e', "catch " + String(eTintCommonW0)); } if (rawWidth <= 0) { - try { if (tintPaletteState.body) rawWidth = Number(tintPaletteState.body.getWidth() || 0); } catch(eTintCommonW1) {} + try { if (tintPaletteState.body) rawWidth = Number(tintPaletteState.body.getWidth() || 0); } catch(eTintCommonW1) { safeLog(null, 'e', "catch " + String(eTintCommonW1)); } } if (rawWidth <= 0) rawWidth = self.dp(320); var marginPx = self.dp(4); @@ -1806,7 +1927,7 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { try { tintPaletteState.commonGrid.removeAllViews(); tintPaletteState.commonGrid.setColumnCount(Math.max(1, Number(layoutInfo.cols || 1))); - } catch(eTintCommonRender0) {} + } catch(eTintCommonRender0) { safeLog(null, 'e', "catch " + String(eTintCommonRender0)); } var tintCi; for (tintCi = 0; tintCi < tintCommonDefs.length; tintCi++) { tintPaletteState.commonGrid.addView(createTintSwatchCell(tintCommonDefs[tintCi].label, tintCommonDefs[tintCi].hex, !!tintCommonDefs[tintCi].followTheme, layoutInfo.cellWidthPx)); @@ -1827,7 +1948,7 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { beforeTextChanged: function(s, st, c, a) {}, onTextChanged: function(s, st, b, c) {} })); - } catch(eTwIcon2) {} + } catch(eTwIcon2) { safeLog(null, 'e', "catch " + String(eTwIcon2)); } try { tintCommonGrid.getViewTreeObserver().addOnGlobalLayoutListener(new android.view.ViewTreeObserver.OnGlobalLayoutListener({ onGlobalLayout: function() { @@ -1840,7 +1961,7 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { } } })); - } catch(eTintCommonLayout0) {} + } catch(eTintCommonLayout0) { safeLog(null, 'e', "catch " + String(eTintCommonLayout0)); } // 图标类型切换函数 function updateIconInputs(type) { if (type === "file") { @@ -1850,7 +1971,7 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { inputShortXIconTint.view.setVisibility(android.view.View.GONE); tintPaletteWrap.setVisibility(android.view.View.GONE); shortxPickerState.expanded = false; - try { if (shortxPickerState.toggleBtn) shortxPickerState.toggleBtn.setText(getShortXPickerClosedLabel()); } catch(eBt0) {} + try { if (shortxPickerState.toggleBtn) shortxPickerState.toggleBtn.setText(getShortXPickerClosedLabel()); } catch(eBt0) { safeLog(null, 'e', "catch " + String(eBt0)); } currentShortXIconName = ""; inputShortXIconTint.input.setText(""); } else if (type === "shortx") { @@ -1904,7 +2025,7 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { android.widget.LinearLayout.LayoutParams.WRAP_CONTENT ); typeWrap.setLayoutParams(_lpTW); - } catch (eLpTW) {} + } catch(eLpTW) { safeLog(null, 'e', "catch " + String(eLpTW)); } var typeLbl = new android.widget.TextView(context); typeLbl.setText("动作类型 (Action Type)"); @@ -1916,14 +2037,14 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { var typeGrid = new android.widget.GridLayout(context); try { typeGrid.setOrientation(android.widget.GridLayout.HORIZONTAL); - } catch (eOri) {} + } catch(eOri) { safeLog(null, 'e', "catch " + String(eOri)); } try { var _lpTG = new android.widget.LinearLayout.LayoutParams( android.widget.LinearLayout.LayoutParams.MATCH_PARENT, android.widget.LinearLayout.LayoutParams.WRAP_CONTENT ); typeGrid.setLayoutParams(_lpTG); - } catch (eLpTG) {} + } catch(eLpTG) { safeLog(null, 'e', "catch " + String(eLpTG)); } typeGrid.setPadding(0, self.dp(6), 0, 0); typeWrap.addView(typeGrid); @@ -1947,7 +2068,7 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { break; } } - } catch (eSel0) {} + } catch(eSel0) { safeLog(null, 'e', "catch " + String(eSel0)); } function applySelectedType(val) { // 这段代码的主要内容/用途:更新选中值并刷新动态输入区可见性。 @@ -1955,7 +2076,7 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { if (!val) val = "shell"; selectedTypeVal = String(val); updateVisibility(selectedTypeVal); - } catch (e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } // 创建 RadioButton(只创建一次) @@ -1964,11 +2085,11 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { rb.setText(types[i].txt); rb.setTextColor(textColor); rb.setTag(types[i].val); - try { rb.setChecked(types[i].val === selectedTypeVal); } catch (eC0) {} - try { rb.setSingleLine(true); } catch (eSL) {} - try { rb.setEllipsize(android.text.TextUtils.TruncateAt.END); } catch (eEl) {} - try { rb.setMinWidth(0); } catch (eMW) {} - try { rb.setMinHeight(self.dp(40)); } catch (eMH) {} + try { rb.setChecked(types[i].val === selectedTypeVal); } catch(eC0) { safeLog(null, 'e', "catch " + String(eC0)); } + try { rb.setSingleLine(true); } catch(eSL) { safeLog(null, 'e', "catch " + String(eSL)); } + try { rb.setEllipsize(android.text.TextUtils.TruncateAt.END); } catch(eEl) { safeLog(null, 'e', "catch " + String(eEl)); } + try { rb.setMinWidth(0); } catch(eMW) { safeLog(null, 'e', "catch " + String(eMW)); } + try { rb.setMinHeight(self.dp(40)); } catch(eMH) { safeLog(null, 'e', "catch " + String(eMH)); } rb.setPadding(self.dp(8), self.dp(6), self.dp(8), self.dp(6)); // 互斥选择 @@ -1988,7 +2109,7 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { for (var k = 0; k < typeRbList.length; k++) { var other = typeRbList[k]; if (other && other !== buttonView) { - try { other.setChecked(false); } catch (eOff) {} + try { other.setChecked(false); } catch(eOff) { safeLog(null, 'e', "catch " + String(eOff)); } } } @@ -2008,7 +2129,7 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { function rebuildTypeGrid() { // 这段代码的主要内容/用途:按当前宽度计算列数(1~3),重建 GridLayout,实现自动换行。 - try { typeGrid.removeAllViews(); } catch (e0) {} + try { typeGrid.removeAllViews(); } catch(e0) { safeLog(null, 'e', "catch " + String(e0)); } var availW = 0; try { availW = typeWrap.getWidth() - self.dp(8); } catch (e1) { availW = 0; } @@ -2032,7 +2153,7 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { if (cols < 1) cols = 1; if (cols > 3) cols = 3; } - try { typeGrid.setColumnCount(cols); } catch (eC) {} + try { typeGrid.setColumnCount(cols); } catch(eC) { safeLog(null, 'e', "catch " + String(eC)); } // 单元宽度:按列数均分 var cellW = 0; @@ -2054,14 +2175,14 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { lp.height = android.widget.LinearLayout.LayoutParams.WRAP_CONTENT; lp.setMargins(0, self.dp(6), self.dp(8), 0); rb.setLayoutParams(lp); - } catch (eLP) {} + } catch(eLP) { safeLog(null, 'e', "catch " + String(eLP)); } - try { typeGrid.addView(rb); } catch (eAdd) {} + try { typeGrid.addView(rb); } catch(eAdd) { safeLog(null, 'e', "catch " + String(eAdd)); } } } // 首次:先渲染一次(保证立即可见) - try { rebuildTypeGrid(); } catch (eR0) {} + try { rebuildTypeGrid(); } catch(eR0) { safeLog(null, 'e', "catch " + String(eR0)); } // 布局变化时:重新计算列数(旋转/宽度变化/首次测量完成) try { @@ -2071,10 +2192,10 @@ FloatBallAppWM.prototype.buildButtonEditorPanelView = function() { if ((r - l) !== (orr - ol)) { rebuildTypeGrid(); } - } catch (eL) {} + } catch(eL) { safeLog(null, 'e', "catch " + String(eL)); } } })); - } catch (eLC) {} + } catch(eLC) { safeLog(null, 'e', "catch " + String(eLC)); } form.addView(typeWrap); // 3. 动态输入区 @@ -2136,8 +2257,8 @@ appWrap.addView(inputAppLaunchUser.view); // # UI 优化:快捷方式类型下,包名与 shortcutId 属于"内部字段",不再在界面上占空间显示 // # 需求:当按钮类型选中快捷方式时,UI 不显示包名/ID,改为显示快捷方式的启动命令(am start intent) // # 说明:仍然保留 pkg/shortcutId 用于数据保存与图标解析,但将输入框隐藏。 - try { inputScPkg.view.setVisibility(android.view.View.GONE); } catch(eHidePkg) {} - try { inputScId.view.setVisibility(android.view.View.GONE); } catch(eHideId) {} + try { inputScPkg.view.setVisibility(android.view.View.GONE); } catch(eHidePkg) { safeLog(null, 'e', "catch " + String(eHidePkg)); } + try { inputScId.view.setVisibility(android.view.View.GONE); } catch(eHideId) { safeLog(null, 'e', "catch " + String(eHideId)); } // # 显示:快捷方式启动命令(只读展示,方便复制/核对) function __scBuildLaunchCmd() { @@ -2156,18 +2277,18 @@ appWrap.addView(inputAppLaunchUser.view); var inputScCmd = self.ui.createInputGroup(self, "快捷方式启动命令 (am start)", __scBuildLaunchCmd(), false, "选择快捷方式后自动生成,可复制到 Termux 验证"); shortcutWrap.addView(inputScCmd.view); // # 需求:快捷方式只使用 JavaScript 执行,取消 Shell,因此隐藏 am start 命令框 - try { inputScCmd.view.setVisibility(android.view.View.GONE); } catch(eHideScCmd) {} + try { inputScCmd.view.setVisibility(android.view.View.GONE); } catch(eHideScCmd) { safeLog(null, 'e', "catch " + String(eHideScCmd)); } try { // # 命令框可编辑:允许你在配置时手动指定/微调启动命令(例如锁定分身/主微信) // # 注意:选择快捷方式后仍会自动刷新该字段;如需保留手动内容,可在选择后再修改。 inputScCmd.input.setEnabled(true); inputScCmd.input.setFocusable(true); inputScCmd.input.setFocusableInTouchMode(true); - try { inputScCmd.input.setSingleLine(false); } catch(eSL) {} - try { inputScCmd.input.setMinLines(2); } catch(eML) {} - try { inputScCmd.input.setHorizontallyScrolling(false); } catch(eHS) {} - try { inputScCmd.input.setTextIsSelectable(true); } catch(eSel) {} - } catch(eRO) {} + try { inputScCmd.input.setSingleLine(false); } catch(eSL) { safeLog(null, 'e', "catch " + String(eSL)); } + try { inputScCmd.input.setMinLines(2); } catch(eML) { safeLog(null, 'e', "catch " + String(eML)); } + try { inputScCmd.input.setHorizontallyScrolling(false); } catch(eHS) { safeLog(null, 'e', "catch " + String(eHS)); } + try { inputScCmd.input.setTextIsSelectable(true); } catch(eSel) { safeLog(null, 'e', "catch " + String(eSel)); } + } catch(eRO) { safeLog(null, 'e', "catch " + String(eRO)); } // # 快捷方式 JS 启动代码(自动生成,可手动微调) // 这段代码的主要内容/用途:为"快捷方式按钮"提供可执行的 JS 启动脚本(默认走 startIntentAsUserByUri),用于精确指定主/分身 userId 并避免弹选择器。 @@ -2187,7 +2308,7 @@ appWrap.addView(inputAppLaunchUser.view); var lu = parseInt(String(targetBtn.launchUserId), 10); if (!isNaN(lu)) u0 = lu; } - } catch (eLuSc) {} + } catch(eLuSc) { safeLog(null, 'e', "catch " + String(eLuSc)); } var iu0 = scSelectedIntentUri ? String(scSelectedIntentUri) : ""; if (!iu0 || iu0.length === 0) { @@ -2226,7 +2347,7 @@ appWrap.addView(inputAppLaunchUser.view); if (inputScJsCode && inputScJsCode.input) { inputScJsCode.input.setText(String(__scBuildDefaultJsCode())); } - } catch(eUpJs) {} + } catch(eUpJs) { safeLog(null, 'e', "catch " + String(eUpJs)); } } var inputScJsCode = self.ui.createInputGroup(self, "快捷方式 JS 启动代码 (startActivityAsUser)", (targetBtn.shortcutJsCode ? String(targetBtn.shortcutJsCode) : ""), false, "选择快捷方式后自动生成;你也可以手动改 userId 或其他参数"); @@ -2237,12 +2358,12 @@ appWrap.addView(inputAppLaunchUser.view); inputScJsCode.input.setEnabled(true); inputScJsCode.input.setFocusable(true); inputScJsCode.input.setFocusableInTouchMode(true); - try { inputScJsCode.input.setSingleLine(false); } catch(eJsSL) {} - try { inputScJsCode.input.setMinLines(2); } catch(eJsML) {} - try { inputScJsCode.input.setMaxLines(4); } catch(eJsMXL) {} - try { inputScJsCode.input.setHorizontallyScrolling(false); } catch(eJsHS) {} - try { inputScJsCode.input.setTextIsSelectable(true); } catch(eJsSel) {} - } catch(eJsBox) {} + try { inputScJsCode.input.setSingleLine(false); } catch(eJsSL) { safeLog(null, 'e', "catch " + String(eJsSL)); } + try { inputScJsCode.input.setMinLines(2); } catch(eJsML) { safeLog(null, 'e', "catch " + String(eJsML)); } + try { inputScJsCode.input.setMaxLines(4); } catch(eJsMXL) { safeLog(null, 'e', "catch " + String(eJsMXL)); } + try { inputScJsCode.input.setHorizontallyScrolling(false); } catch(eJsHS) { safeLog(null, 'e', "catch " + String(eJsHS)); } + try { inputScJsCode.input.setTextIsSelectable(true); } catch(eJsSel) { safeLog(null, 'e', "catch " + String(eJsSel)); } + } catch(eJsBox) { safeLog(null, 'e', "catch " + String(eJsBox)); } // # 快捷方式选择器(内联折叠版):在"新增/编辑按钮页"内部展开/收起列表,并回填 pkg/shortcutId // 这段代码的主要内容/用途:把原先"弹出选择器窗口"的方式改为"折叠展开在本页下方显示",避免上下层遮挡问题。 @@ -2281,13 +2402,13 @@ function __scLoadIconForItem(it) { var dr = la.getShortcutIconDrawable(it.shortcutInfo, 0); if (dr) return dr; } - } catch(eS0) {} + } catch(eS0) { safeLog(null, 'e', "catch " + String(eS0)); } } try { var pm = context.getPackageManager(); return pm.getApplicationIcon(__scStr(it.pkg)); - } catch(eA0) {} - } catch(eAll0) {} + } catch(eA0) { safeLog(null, 'e', "catch " + String(eA0)); } + } catch(eAll0) { safeLog(null, 'e', "catch " + String(eAll0)); } return null; } function __scEnqueueIconLoad(it, iv) { @@ -2295,11 +2416,11 @@ function __scEnqueueIconLoad(it, iv) { var key = __scIconKey(it); if (!key) return; if (scIconCache[key]) { - try { iv.setImageDrawable(scIconCache[key]); } catch(eSet0) {} + try { iv.setImageDrawable(scIconCache[key]); } catch(eSet0) { safeLog(null, 'e', "catch " + String(eSet0)); } return; } // # 记录 tag:防止滚动/重绘后错位 - try { iv.setTag(key); } catch(eTag0) {} + try { iv.setTag(key); } catch(eTag0) { safeLog(null, 'e', "catch " + String(eTag0)); } scIconQueue.push({ key: key, it: it, iv: iv }); if (!scIconWorkerRunning) { scIconWorkerRunning = true; @@ -2323,15 +2444,15 @@ function __scEnqueueIconLoad(it, iv) { if (cur && String(cur) === String(job.key) && dr) { job.iv.setImageDrawable(dr); } - } catch(eUi0) {} + } catch(eUi0) { safeLog(null, 'e', "catch " + String(eUi0)); } }); - } catch(ePost0) {} + } catch(ePost0) { safeLog(null, 'e', "catch " + String(ePost0)); } } scIconWorkerRunning = false; } })).start(); } - } catch(eEnq0) {} + } catch(eEnq0) { safeLog(null, 'e', "catch " + String(eEnq0)); } } // # 折叠头部(点击展开/收起) @@ -2362,12 +2483,12 @@ scRefreshTv.setOnClickListener(new android.view.View.OnClickListener({ scInlineState.forceReload = true; scInlineState.loaded = false; // 清空 icon 缓存,避免旧图标占用内存且影响新列表显示 - try { scIconCache = {}; } catch(eC0) {} - try { scIconQueue = []; } catch(eC1) {} - try { scIconWorkerRunning = false; } catch(eC2) {} + try { scIconCache = {}; } catch(eC0) { safeLog(null, 'e', "catch " + String(eC0)); } + try { scIconQueue = []; } catch(eC1) { safeLog(null, 'e', "catch " + String(eC1)); } + try { scIconWorkerRunning = false; } catch(eC2) { safeLog(null, 'e', "catch " + String(eC2)); } // 若当前已展开,立即触发重新加载与渲染 if (scInlineState.expanded) __scEnsureLoadedAndRender(); - } catch(eR) {} + } catch(eR) { safeLog(null, 'e', "catch " + String(eR)); } } })); scHeader.addView(scRefreshTv); @@ -2411,7 +2532,7 @@ try { if (targetPx > maxPx) targetPx = maxPx; var lpBox = new android.widget.LinearLayout.LayoutParams(-1, targetPx); scListBox.setLayoutParams(lpBox); -} catch(eH0) {} + } catch(eH0) { safeLog(null, 'e', "catch " + String(eH0)); } try { // # 列表框描边+圆角 var gdBox = new android.graphics.drawable.GradientDrawable(); @@ -2422,14 +2543,14 @@ try { gdBox.setStroke(self.dp(1), _isDark0 ? C.dividerDark : C.dividerLight); scListBox.setBackground(gdBox); scListBox.setPadding(self.dp(6), self.dp(6), self.dp(6), self.dp(6)); -} catch(eBg0) {} + } catch(eBg0) { safeLog(null, 'e', "catch " + String(eBg0)); } // # ListView:真正的列表控件(支持框内纵向滚动) var scList = new android.widget.ListView(context); -try { scList.setDivider(null); } catch(eDiv0) {} -try { scList.setVerticalScrollBarEnabled(true); } catch(eSb0) {} -try { scList.setOverScrollMode(android.view.View.OVER_SCROLL_IF_CONTENT_SCROLLS); } catch(eOver0) {} -try { scList.setCacheColorHint(android.graphics.Color.TRANSPARENT); } catch(eCch0) {} +try { scList.setDivider(null); } catch(eDiv0) { safeLog(null, 'e', "catch " + String(eDiv0)); } +try { scList.setVerticalScrollBarEnabled(true); } catch(eSb0) { safeLog(null, 'e', "catch " + String(eSb0)); } +try { scList.setOverScrollMode(android.view.View.OVER_SCROLL_IF_CONTENT_SCROLLS); } catch(eOver0) { safeLog(null, 'e', "catch " + String(eOver0)); } +try { scList.setCacheColorHint(android.graphics.Color.TRANSPARENT); } catch(eCch0) { safeLog(null, 'e', "catch " + String(eCch0)); } try { // # 关键:列表内滑动时,禁止父容器拦截触摸事件(DOWN/MOVE 都做) scList.setOnTouchListener(new android.view.View.OnTouchListener({ @@ -2441,17 +2562,17 @@ try { // # 向上递归,避免多层父布局抢事件 var p = v.getParent(); while (p != null) { - try { p.requestDisallowInterceptTouchEvent(true); } catch(eReq) {} + try { p.requestDisallowInterceptTouchEvent(true); } catch(eReq) { safeLog(null, 'e', "catch " + String(eReq)); } try { p = p.getParent(); } catch(eUp) { p = null; } } - } catch(ePar0) {} + } catch(ePar0) { safeLog(null, 'e', "catch " + String(ePar0)); } } - } catch(eTouch0) {} + } catch(eTouch0) { safeLog(null, 'e', "catch " + String(eTouch0)); } // # 返回 false:让 ListView 自己处理滚动 return false; } })); -} catch(eT0) {} + } catch(eT0) { safeLog(null, 'e', "catch " + String(eT0)); } scListBox.addView(scList, new android.widget.FrameLayout.LayoutParams(-1, -1)); @@ -2469,7 +2590,7 @@ var __scIconInFlight = {}; var __scIconLoader = (function() { try { if (self.__scIconLoaderSingleton) return self.__scIconLoaderSingleton; - } catch(eS) {} + } catch(eS) { safeLog(null, 'e', "catch " + String(eS)); } var obj = { ht: null, h: null }; try { @@ -2483,17 +2604,17 @@ var __scIconLoader = (function() { obj.h = null; } - try { self.__scIconLoaderSingleton = obj; } catch(eSet) {} + try { self.__scIconLoaderSingleton = obj; } catch(eSet) { safeLog(null, 'e', "catch " + String(eSet)); } return obj; })(); function __scPostIconLoad(fn) { try { if (__scIconLoader && __scIconLoader.h) { - __scIconLoader.h.post(new java.lang.Runnable({ run: function() { try { fn(); } catch(e) {} } })); + __scIconLoader.h.post(new java.lang.Runnable({ run: function() { try { fn(); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } })); return true; } - } catch(eP) {} + } catch(eP) { safeLog(null, 'e', "catch " + String(eP)); } return false; } @@ -2503,12 +2624,12 @@ function __scRequestIcon(it, imageView) { var key = String(it.pkg) + "|" + String(it.shortcutId); // 绑定 tag:后续回调时校验,避免复用行导致串图 - try { imageView.setTag(key); } catch(eTag0) {} + try { imageView.setTag(key); } catch(eTag0) { safeLog(null, 'e', "catch " + String(eTag0)); } // 命中缓存:直接显示 var hit = __scGetIcon(key); if (hit) { - try { imageView.setImageDrawable(hit); } catch(eSet0) {} + try { imageView.setImageDrawable(hit); } catch(eSet0) { safeLog(null, 'e', "catch " + String(eSet0)); } return; } @@ -2517,10 +2638,10 @@ function __scRequestIcon(it, imageView) { if (__scPm) { var appDr = __scPm.getApplicationIcon(String(it.pkg)); if (appDr) { - try { imageView.setImageDrawable(appDr); } catch(eSet1) {} + try { imageView.setImageDrawable(appDr); } catch(eSet1) { safeLog(null, 'e', "catch " + String(eSet1)); } } } - } catch(eApp0) {} + } catch(eApp0) { safeLog(null, 'e', "catch " + String(eApp0)); } // 已在加载中:不重复排队 if (__scIconInFlight[key]) return; @@ -2537,7 +2658,7 @@ function __scRequestIcon(it, imageView) { if (dr) __scPutIcon(key, dr); - try { delete __scIconInFlight[key]; } catch(eDel0) {} + try { delete __scIconInFlight[key]; } catch(eDel0) { safeLog(null, 'e', "catch " + String(eDel0)); } try { // 回到 UI:只更新 tag 仍然匹配的行 @@ -2547,13 +2668,13 @@ function __scRequestIcon(it, imageView) { var tag = null; try { tag = imageView.getTag(); } catch(eTg) { tag = null; } if (String(tag) === String(key)) { - try { imageView.setImageDrawable(dr); } catch(eSet2) {} + try { imageView.setImageDrawable(dr); } catch(eSet2) { safeLog(null, 'e', "catch " + String(eSet2)); } } - } catch(eUi0) {} + } catch(eUi0) { safeLog(null, 'e', "catch " + String(eUi0)); } }})); - } catch(eUi1) {} + } catch(eUi1) { safeLog(null, 'e', "catch " + String(eUi1)); } }); - } catch(eR) {} + } catch(eR) { safeLog(null, 'e', "catch " + String(eR)); } } function __scPutIcon(k, d) { try { @@ -2563,9 +2684,9 @@ function __scPutIcon(k, d) { __scIconKeys.push(k); if (__scIconKeys.length > __scIconMax) { var old = __scIconKeys.shift(); - try { delete __scIconCache[old]; } catch(eDel) {} + try { delete __scIconCache[old]; } catch(eDel) { safeLog(null, 'e', "catch " + String(eDel)); } } - } catch(ePut) {} + } catch(ePut) { safeLog(null, 'e', "catch " + String(ePut)); } } function __scGetIcon(k) { try { return __scIconCache[k] || null; } catch(eGet) { return null; } @@ -2575,8 +2696,8 @@ function __scGetIcon(k) { var __scData = []; var __scLauncherApps = null; var __scPm = null; -try { __scLauncherApps = context.getSystemService(android.content.Context.LAUNCHER_APPS_SERVICE); } catch(eLa0) {} -try { __scPm = context.getPackageManager(); } catch(ePm0) {} +try { __scLauncherApps = context.getSystemService(android.content.Context.LAUNCHER_APPS_SERVICE); } catch(eLa0) { safeLog(null, 'e', "catch " + String(eLa0)); } +try { __scPm = context.getPackageManager(); } catch(ePm0) { safeLog(null, 'e', "catch " + String(ePm0)); } // # 新增:应用名缓存 // 这段代码的主要内容/用途:把包名解析成应用名(ApplicationLabel),并做缓存,避免列表滚动时频繁调用 PackageManager。 @@ -2608,7 +2729,7 @@ function __scGetAppLabel(pkg) { __scAppLabelCacheKeys.push(p); if (__scAppLabelCacheKeys.length > __scAppLabelCacheMax) { var old = __scAppLabelCacheKeys.shift(); - try { delete __scAppLabelCache[old]; } catch(eDel) {} + try { delete __scAppLabelCache[old]; } catch(eDel) { safeLog(null, 'e', "catch " + String(eDel)); } } return lb; @@ -2634,7 +2755,7 @@ var __scAdapter = new android.widget.BaseAdapter({ var _isDark1 = self.isDarkTheme(); var bg = self.ui.createRoundDrawable(_isDark1 ? C.cardDark : C.cardLight, self.dp(10)); row.setBackground(bg); - } catch(eBg1) {} + } catch(eBg1) { safeLog(null, 'e', "catch " + String(eBg1)); } var iv = new android.widget.ImageView(context); var lpIv = new android.widget.LinearLayout.LayoutParams(self.dp(36), self.dp(36)); @@ -2666,7 +2787,7 @@ var __scAdapter = new android.widget.BaseAdapter({ } else { holder = row.getTag(); } - } catch(eRow0) {} + } catch(eRow0) { safeLog(null, 'e', "catch " + String(eRow0)); } try { var it = __scData[pos]; @@ -2682,14 +2803,14 @@ var __scAdapter = new android.widget.BaseAdapter({ // # icon:异步加载 shortcut icon,UI 线程先回退 app icon,避免滚动/渲染卡顿 // 这段代码的主要内容/用途:把耗时的 shortcut icon 获取移到后台线程,列表滚动更顺滑、system_server 占用更稳。 -try { __scRequestIcon(it, holder.iv); } catch(eIconReq) {} +try { __scRequestIcon(it, holder.iv); } catch(eIconReq) { safeLog(null, 'e', "catch " + String(eIconReq)); } } - } catch(eBind) {} + } catch(eBind) { safeLog(null, 'e', "catch " + String(eBind)); } return row; } }); -try { scList.setAdapter(__scAdapter); } catch(eAd0) {} +try { scList.setAdapter(__scAdapter); } catch(eAd0) { safeLog(null, 'e', "catch " + String(eAd0)); } try { scList.setOnItemClickListener(new android.widget.AdapterView.OnItemClickListener({ @@ -2698,14 +2819,14 @@ try { var obj = __scData[position]; if (!obj) return; - try { inputScPkg.input.setText(String(obj.pkg)); } catch(eSet1) {} - try { inputScId.input.setText(String(obj.shortcutId)); } catch(eSet2) {} + try { inputScPkg.input.setText(String(obj.pkg)); } catch(eSet1) { safeLog(null, 'e', "catch " + String(eSet1)); } + try { inputScId.input.setText(String(obj.shortcutId)); } catch(eSet2) { safeLog(null, 'e', "catch " + String(eSet2)); } // # 回填:用于"Shell am start"启动的 intentUri + userId(桌面移除后仍可启动) try { scSelectedIntentUri = obj.intentUri ? String(obj.intentUri) : ""; } catch(eSetIU) { scSelectedIntentUri = ""; } try { scSelectedUserId = (obj.userId != null) ? parseInt(String(obj.userId), 10) : 0; } catch(eSetUID) { scSelectedUserId = 0; } // # 同步刷新:启动命令展示框 - try { if (inputScCmd && inputScCmd.input) inputScCmd.input.setText(String(__scBuildLaunchCmd())); } catch(eUpCmd) {} + try { if (inputScCmd && inputScCmd.input) inputScCmd.input.setText(String(__scBuildLaunchCmd())); } catch(eUpCmd) { safeLog(null, 'e', "catch " + String(eUpCmd)); } // # 同步刷新:JS 启动代码(选择快捷方式后自动生成并回填) __scUpdateJsCodeSafe(); @@ -2715,9 +2836,9 @@ try { try { var __scIconPath = __scEnsureShortcutIconFile(obj); if (__scIconPath) { - try { inputIconPath.input.setText(String(__scIconPath)); } catch(eSetIP) {} + try { inputIconPath.input.setText(String(__scIconPath)); } catch(eSetIP) { safeLog(null, 'e', "catch " + String(eSetIP)); } } - } catch(eExp0) {} + } catch(eExp0) { safeLog(null, 'e', "catch " + String(eExp0)); } // 可选:标题为空时自动填 label try { @@ -2725,9 +2846,9 @@ try { if ((!curTitle || curTitle.trim().length === 0) && obj.label) { inputTitle.input.setText(String(obj.label)); } - } catch(eSet3) {} + } catch(eSet3) { safeLog(null, 'e', "catch " + String(eSet3)); } - try { self.state.pendingDirty = true; } catch(eDirty) {} + try { self.state.pendingDirty = true; } catch(eDirty) { safeLog(null, 'e', "catch " + String(eDirty)); } // # 收起列表 try { @@ -2741,130 +2862,19 @@ try { var _nm = String(obj.label || obj.shortcutId || "快捷方式"); if (_app && _app.length > 0) scHeaderTv.setText("已选择:" + String(_app) + "/" + _nm + "(点击展开)"); else scHeaderTv.setText("已选择:" + _nm + "(点击展开)"); - } catch(eFold) {} + } catch(eFold) { safeLog(null, 'e', "catch " + String(eFold)); } } catch(eCb) { - try { self.toast("回填失败: " + eCb); } catch(eT) {} + try { self.toast("回填失败: " + eCb); } catch(eT) { safeLog(null, 'e', "catch " + String(eT)); } } } })); -} catch(eClk0) {} + } catch(eClk0) { safeLog(null, 'e', "catch " + String(eClk0)); } // # 工具函数:安全字符串 -function __scStr(v) { try { return String(v == null ? "" : v); } catch(e) { return ""; } } -function __scLower(v) { try { return __scStr(v).toLowerCase(); } catch(e) { return ""; } } // # 工具函数:导出快捷方式图标到 shortcut_icons 并返回路径 -function __scEnsureShortcutIconFile(item) { - // 这段代码的主要内容/用途:把 Launcher Shortcuts 的图标在"可见时"持久化为 PNG,后续按钮页直接读文件显示,避免桌面移除后图标退化/缺失。 - try { - if (!item) return ""; - var pkg = __scStr(item.pkg); - var sid = __scStr(item.shortcutId); - var uid = (item.userId != null) ? __scStr(item.userId) : "0"; - if (!pkg || !sid) return ""; - var dir = String(APP_ROOT_DIR) + "/shortcut_icons"; - try { - var d = new java.io.File(dir); - if (!d.exists()) d.mkdirs(); - } catch(eMk) {} - // # 与主程序同名规则:pkg__sid__u{uid}.png - var fn = __scSanitizeFileName(pkg) + "__" + __scSanitizeFileName(sid) + "__u" + __scSanitizeFileName(uid) + ".png"; - var outPath = dir + "/" + fn; - - // # 已存在则直接复用 - try { - var f = new java.io.File(outPath); - if (f.exists() && f.isFile() && f.length() > 0) return outPath; - } catch(eEx) {} - - // # 获取 Drawable(优先 shortcut icon,失败则回退 app icon) - var dr = null; - try { - if (__scLauncherApps && item.shortcutInfo) { - try { dr = __scLauncherApps.getShortcutIconDrawable(item.shortcutInfo, 0); } catch(eD0) { dr = null; } - } - } catch(eLA) { dr = null; } - if (!dr) { - try { - var pm = context.getPackageManager(); - dr = pm.getApplicationIcon(pkg); - } catch(eApp) { dr = null; } - } - if (!dr) return ""; - - // # Drawable -> Bitmap -> PNG - var bmp = null; - try { bmp = __scDrawableToBitmap(dr, 192); } catch(eBmp) { bmp = null; } - if (!bmp) return ""; - - var fos = null; - try { - fos = new java.io.FileOutputStream(outPath); - bmp.compress(android.graphics.Bitmap.CompressFormat.PNG, 100, fos); - try { fos.flush(); } catch(eFl) {} - try { fos.close(); } catch(eCl) {} - fos = null; - } catch(eW) { - try { if (fos) fos.close(); } catch(eCl2) {} - fos = null; - return ""; - } - - return outPath; - } catch(eAll) { - return ""; - } -} - -function __scSanitizeFileName(s) { - try { - var t = __scStr(s); - t = t.replace(/[^a-zA-Z0-9._-]+/g, "_"); - if (t.length > 120) t = t.substring(0, 120); - return t; - } catch(e) { return ""; } -} - -function __scDrawableToBitmap(drawable, targetPx) { - // 这段代码的主要内容/用途:把任意 Drawable 安全绘制成 Bitmap,便于持久化保存 PNG。 - try { - if (!drawable) return null; - - // BitmapDrawable 直接取 - try { - if (drawable instanceof android.graphics.drawable.BitmapDrawable) { - var b = drawable.getBitmap(); - if (b) return b; - } - } catch(eBD) {} - - var w = 0, h = 0; - try { w = drawable.getIntrinsicWidth(); } catch(eW) { w = 0; } - try { h = drawable.getIntrinsicHeight(); } catch(eH) { h = 0; } - - if (w <= 0 || h <= 0) { - w = targetPx || 192; - h = targetPx || 192; - } - - // # 过大的直接缩到 targetPx 附近,避免 PNG 体积过大 - var maxSide = targetPx || 192; - var side = Math.max(w, h); - var scale = side > maxSide ? (maxSide / side) : 1.0; - var bw = Math.max(1, Math.round(w * scale)); - var bh = Math.max(1, Math.round(h * scale)); - - var bmp = android.graphics.Bitmap.createBitmap(bw, bh, android.graphics.Bitmap.Config.ARGB_8888); - var canvas = new android.graphics.Canvas(bmp); - drawable.setBounds(0, 0, bw, bh); - drawable.draw(canvas); - return bmp; - } catch(eAll) { - return null; - } -} // # 数据拉取:枚举 userId + packages + LauncherApps.getShortcuts function __scLoadAllItems() { @@ -2881,7 +2891,7 @@ function __scLoadAllItems() { if (typeof getSystemUserDir === "function") { basePath = getSystemUserDir(); } - } catch(eGSD) {} + } catch(eGSD) { safeLog(null, 'e', "catch " + String(eGSD)); } var base = new java.io.File(basePath); if (base.exists() && base.isDirectory()) { @@ -2901,7 +2911,7 @@ function __scLoadAllItems() { } } } - } catch(eU0) {} + } catch(eU0) { safeLog(null, 'e', "catch " + String(eU0)); } if (users.length === 0) users.push(0); // # 修复:与 shortcuts.js 一致,优先使用 shortcut 系统服务直连获取(可见性更全,能覆盖"微信小程序添加到桌面"这类入口) // # 说明:LauncherApps.getShortcuts 在部分 ROM/桌面上返回不全,因此这里先走 IShortcutService.getShortcuts。 @@ -2926,7 +2936,7 @@ function __scLoadAllItems() { if (typeof getSystemUserDir === "function") { basePath2 = getSystemUserDir(); } - } catch(eGSD3) {} + } catch(eGSD3) { safeLog(null, 'e', "catch " + String(eGSD3)); } var dir = new java.io.File(basePath2 + "/" + String(uid) + "/shortcut_service/packages"); if (dir.exists() && dir.isDirectory()) { @@ -2943,7 +2953,7 @@ function __scLoadAllItems() { } } } - } catch(eP0) {} + } catch(eP0) { safeLog(null, 'e', "catch " + String(eP0)); } for (var p = 0; p < pkgs.length; p++) { var pkgName = pkgs[p]; @@ -2992,7 +3002,7 @@ function __scLoadAllItems() { // # 安全阈值:避免极端情况下数据量过大导致 UI/内存压力 if (items.length > 5000) return items; } - } catch(eS3) {} + } catch(eS3) { safeLog(null, 'e', "catch " + String(eS3)); } // # 已拿到则直接处理下一个包,避免重复从 LauncherApps 再取一遍 continue; } @@ -3004,16 +3014,16 @@ function __scLoadAllItems() { // # 兜底:若没有 LauncherApps 服务,则无法走 fallback,直接跳过(上面 shortcutSvc 已尽力) if (!la) continue; var q = new ShortcutQuery(); - try { q.setPackage(pkgName); } catch(eQ0) {} + try { q.setPackage(pkgName); } catch(eQ0) { safeLog(null, 'e', "catch " + String(eQ0)); } // # QueryFlags:尽量全拿(逐个 try,避免 ROM 缺字段) try { var qFlags = 0; - try { qFlags = qFlags | ShortcutQuery.FLAG_MATCH_DYNAMIC; } catch(eF1) {} - try { qFlags = qFlags | ShortcutQuery.FLAG_MATCH_PINNED; } catch(eF2) {} - try { qFlags = qFlags | ShortcutQuery.FLAG_MATCH_MANIFEST; } catch(eF3) {} - try { qFlags = qFlags | ShortcutQuery.FLAG_MATCH_CACHED; } catch(eF4) {} - try { q.setQueryFlags(qFlags); } catch(eF5) {} - } catch(eF0) {} + try { qFlags = qFlags | ShortcutQuery.FLAG_MATCH_DYNAMIC; } catch(eF1) { safeLog(null, 'e', "catch " + String(eF1)); } + try { qFlags = qFlags | ShortcutQuery.FLAG_MATCH_PINNED; } catch(eF2) { safeLog(null, 'e', "catch " + String(eF2)); } + try { qFlags = qFlags | ShortcutQuery.FLAG_MATCH_MANIFEST; } catch(eF3) { safeLog(null, 'e', "catch " + String(eF3)); } + try { qFlags = qFlags | ShortcutQuery.FLAG_MATCH_CACHED; } catch(eF4) { safeLog(null, 'e', "catch " + String(eF4)); } + try { q.setQueryFlags(qFlags); } catch(eF5) { safeLog(null, 'e', "catch " + String(eF5)); } + } catch(eF0) { safeLog(null, 'e', "catch " + String(eF0)); } var uh = null; try { uh = UserHandle.of(parseInt(String(uid), 10)); } catch(eUH) { uh = null; } @@ -3056,7 +3066,7 @@ function __scLoadAllItems() { } } } - } catch(eAll) {} + } catch(eAll) { safeLog(null, 'e', "catch " + String(eAll)); } return items; } @@ -3080,7 +3090,7 @@ function __scRenderListNow(query) { if (hasRendered && scInlineState.__scLastQuery === q && scInlineState.__scLastSrcSize === ((scInlineState.allItems || []).length)) { return; } - } catch(eSame0) {} + } catch(eSame0) { safeLog(null, 'e', "catch " + String(eSame0)); } scInlineState.__scLastQuery = q; try { scInlineState.__scLastSrcSize = (scInlineState.allItems || []).length; } catch(eSz0) { scInlineState.__scLastSrcSize = 0; } @@ -3098,7 +3108,7 @@ function __scRenderListNow(query) { else if (__scLower(it.pkg).indexOf(q) >= 0) hit = true; else if (__scLower(__scGetAppLabel(it.pkg)).indexOf(q) >= 0) hit = true; else if (__scLower(it.shortcutId).indexOf(q) >= 0) hit = true; - } catch(eM) {} + } catch(eM) { safeLog(null, 'e', "catch " + String(eM)); } if (hit) out.push(it); // # 性能保护:搜索时最多显示 300 条,避免 system_server 过载 if (out.length >= 300) break; @@ -3107,34 +3117,34 @@ function __scRenderListNow(query) { // 更新适配器数据 __scData = out; - try { __scAdapter.notifyDataSetChanged(); } catch(eN0) {} + try { __scAdapter.notifyDataSetChanged(); } catch(eN0) { safeLog(null, 'e', "catch " + String(eN0)); } // # 修复:确保首次展开时 ListView 立即刷新布局,不依赖用户触摸触发重绘 - try { scInlineState.__scHasRendered = true; } catch(eHr1) {} + try { scInlineState.__scHasRendered = true; } catch(eHr1) { safeLog(null, 'e', "catch " + String(eHr1)); } try { scList.post(new java.lang.Runnable({ run: function() { - try { scList.invalidateViews(); } catch(eInv0) {} - try { scList.requestLayout(); } catch(eReq0) {} + try { scList.invalidateViews(); } catch(eInv0) { safeLog(null, 'e', "catch " + String(eInv0)); } + try { scList.requestLayout(); } catch(eReq0) { safeLog(null, 'e', "catch " + String(eReq0)); } } })); } catch(ePostInv0) { - try { scList.invalidateViews(); } catch(eInv1) {} + try { scList.invalidateViews(); } catch(eInv1) { safeLog(null, 'e', "catch " + String(eInv1)); } } // 提示信息 try { if (out.length === 0) scHint.setText("无匹配结果(共 " + src.length + " 条)"); else scHint.setText("共 " + src.length + " 条,显示 " + out.length + " 条(在框内滑动)"); - } catch(eH1) {} + } catch(eH1) { safeLog(null, 'e', "catch " + String(eH1)); } } catch(e0) { - try { scHint.setText("渲染失败: " + e0); } catch(e1) {} + try { scHint.setText("渲染失败: " + e0); } catch(e1) { safeLog(null, 'e', "catch " + String(e1)); } } } function __scRenderList(query) { // # 这段代码的主要内容/用途:渲染去抖入口(合并 50ms 内的多次刷新请求) - try { scInlineState.__scPendingQuery = query; } catch(ePQ0) {} + try { scInlineState.__scPendingQuery = query; } catch(ePQ0) { safeLog(null, 'e', "catch " + String(ePQ0)); } // # 初始化 Handler(主线程) try { @@ -3148,7 +3158,7 @@ function __scRenderList(query) { if (__scRenderHandler && __scRenderRunnable) { __scRenderHandler.removeCallbacks(__scRenderRunnable); } - } catch(eRm0) {} + } catch(eRm0) { safeLog(null, 'e', "catch " + String(eRm0)); } // # 创建新的 runnable(始终使用最新 query) __scRenderRunnable = new java.lang.Runnable({ @@ -3193,7 +3203,7 @@ function __scEnsureLoadedAndRender() { } scInlineState.loading = true; - try { scHint.setText("正在加载快捷方式列表..."); } catch(eH0) {} + try { scHint.setText("正在加载快捷方式列表..."); } catch(eH0) { safeLog(null, 'e', "catch " + String(eH0)); } new java.lang.Thread(new java.lang.Runnable({ run: function() { @@ -3216,19 +3226,19 @@ function __scEnsureLoadedAndRender() { scInlineState.loading = false; scInlineState.loaded = true; scInlineState.allItems = arr || []; - } catch(eUi2) {} + } catch(eUi2) { safeLog(null, 'e', "catch " + String(eUi2)); } // # 关键修复:首次展开时也要触发渲染,否则会一直停留在"正在加载..." try { // 优先用 ListView.post:保证在拥有 Looper 的 UI 线程执行 scList.post(new java.lang.Runnable({ run: function() { - try { __scRenderListNow(scSearchWrap.getValue()); } catch(eR0) {} + try { __scRenderListNow(scSearchWrap.getValue()); } catch(eR0) { safeLog(null, 'e', "catch " + String(eR0)); } } })); } catch(ePost0) { // 再兜底:直接调用(若当前线程本就有 Looper 也能工作) - try { __scRenderList(scSearchWrap.getValue()); } catch(eR1) {} + try { __scRenderList(scSearchWrap.getValue()); } catch(eR1) { safeLog(null, 'e', "catch " + String(eR1)); } } } } @@ -3247,18 +3257,18 @@ scHeader.setOnClickListener(new android.view.View.OnClickListener({ try { scList.post(new java.lang.Runnable({ run: function() { - try { scList.requestLayout(); } catch(eRq0) {} - try { scList.invalidateViews(); } catch(eIv0) {} + try { scList.requestLayout(); } catch(eRq0) { safeLog(null, 'e', "catch " + String(eRq0)); } + try { scList.invalidateViews(); } catch(eIv0) { safeLog(null, 'e', "catch " + String(eIv0)); } } })); - } catch(ePostRq0) {} + } catch(ePostRq0) { safeLog(null, 'e', "catch " + String(ePostRq0)); } scArrowTv.setText("▲"); __scEnsureLoadedAndRender(); } else { scBody.setVisibility(android.view.View.GONE); scArrowTv.setText("▼"); } - } catch(eTg) {} + } catch(eTg) { safeLog(null, 'e', "catch " + String(eTg)); } } })); @@ -3278,23 +3288,23 @@ try { if (scInlineState.__scSearchRunnable) { scList.removeCallbacks(scInlineState.__scSearchRunnable); } - } catch(eRm) {} + } catch(eRm) { safeLog(null, 'e', "catch " + String(eRm)); } scInlineState.__scSearchRunnable = new java.lang.Runnable({ run: function() { try { // # 再次确认当前查询未变化(防抖期间用户继续输入) __scRenderList(q); - } catch(eRun) {} + } catch(eRun) { safeLog(null, 'e', "catch " + String(eRun)); } } }); // # 180ms 防抖:既跟手又不抖 CPU try { scList.postDelayed(scInlineState.__scSearchRunnable, 180); } catch(ePost) { __scRenderList(q); } - } catch(eW) {} + } catch(eW) { safeLog(null, 'e', "catch " + String(eW)); } } })); -} catch(eTw) {} + } catch(eTw) { safeLog(null, 'e', "catch " + String(eTw)); } // # 组装到 shortcutWrap shortcutWrap.addView(scHeader); @@ -3352,7 +3362,7 @@ shortcutWrap.addView(scBody); // # 保存 ShortX 图标颜色:优先使用 targetBtn.iconTint(颜色选择器已更新),回退到输入框 var sxTint = currentShortXIconTint || targetBtn.iconTint || ""; if (!sxTint) { - try { sxTint = inputShortXIconTint.getValue(); } catch(eGetTint) {} + try { sxTint = inputShortXIconTint.getValue(); } catch(eGetTint) { safeLog(null, 'e', "catch " + String(eGetTint)); } } if (sxTint && sxTint.length > 0) newBtn.iconTint = sxTint; else delete newBtn.iconTint; delete newBtn.iconPath; // 清除文件路径 @@ -3385,7 +3395,7 @@ try { var aui = parseInt(au, 10); if (!isNaN(aui)) newBtn.launchUserId = aui; } -} catch(eAU) {} + } catch(eAU) { safeLog(null, 'e', "catch " + String(eAU)); } } else if (newBtn.type === "broadcast") { var a = inputAction.getValue(); @@ -3405,10 +3415,10 @@ try { if (!sid) { inputScId.setError("请输入 shortcutId"); isValid=false; } else { inputScId.setError(null); newBtn.shortcutId = sid; } // # 保存:同时保存 intentUri/userId,供 JavaScript(startActivityAsUser) 脚本使用(锁定主/分身) - try { if (scSelectedIntentUri && scSelectedIntentUri.length > 0) newBtn.intentUri = String(scSelectedIntentUri); } catch(eSIU2) {} + try { if (scSelectedIntentUri && scSelectedIntentUri.length > 0) newBtn.intentUri = String(scSelectedIntentUri); } catch(eSIU2) { safeLog(null, 'e', "catch " + String(eSIU2)); } try { newBtn.userId = scSelectedUserId; } catch(eSUID2) { newBtn.userId = 0; } // # 保存:快捷方式 JS 启动代码(自动生成/可手动编辑) - try { if (inputScJsCode) newBtn.shortcutJsCode = String(inputScJsCode.getValue()); } catch(eSaveJs) {} + try { if (inputScJsCode) newBtn.shortcutJsCode = String(inputScJsCode.getValue()); } catch(eSaveJs) { safeLog(null, 'e', "catch " + String(eSaveJs)); } } // # 保存:快捷方式仅使用 JavaScript 执行(取消 Shell/兜底) newBtn.shortcutRunMode = "js"; @@ -3526,7 +3536,7 @@ FloatBallAppWM.prototype.buildSchemaEditorPanelView = function() { // List var scroll = new android.widget.ScrollView(context); - try { scroll.setVerticalScrollBarEnabled(false); } catch(e){} + try { scroll.setVerticalScrollBarEnabled(false); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } var list = new android.widget.LinearLayout(context); list.setOrientation(android.widget.LinearLayout.VERTICAL); list.setPadding(0, self.dp(4), 0, self.dp(4)); @@ -3539,7 +3549,7 @@ FloatBallAppWM.prototype.buildSchemaEditorPanelView = function() { card.setOrientation(android.widget.LinearLayout.HORIZONTAL); card.setGravity(android.view.Gravity.CENTER_VERTICAL); card.setBackground(self.ui.createRoundDrawable(cardColor, self.dp(8))); - try { card.setElevation(self.dp(2)); } catch(e){} + try { card.setElevation(self.dp(2)); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } var cardLp = new android.widget.LinearLayout.LayoutParams(android.widget.LinearLayout.LayoutParams.MATCH_PARENT, android.widget.LinearLayout.LayoutParams.WRAP_CONTENT); cardLp.setMargins(self.dp(2), self.dp(4), self.dp(2), self.dp(4)); @@ -3815,9 +3825,9 @@ FloatBallAppWM.prototype.showPopupOverlay = function(opts) { try { wm.addView(root, lp); } catch(eAdd) { safeLog(self.L, 'e', "popup addView fail: " + String(eAdd)); return null; } function closePopup() { - try { wm.removeView(root); } catch(e) {} + try { wm.removeView(root); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } if (typeof onDismiss === "function") { - try { onDismiss(); } catch(eD) {} + try { onDismiss(); } catch(eD) { safeLog(null, 'e', "catch " + String(eD)); } } } @@ -3836,9 +3846,9 @@ FloatBallAppWM.prototype.showShortXIconPickerPopup = function(opts) { var onDismissCb = (typeof opt.onDismiss === "function") ? opt.onDismiss : null; var catalog = []; - try { catalog = self.getShortXIconCatalog() || []; } catch(e) {} + try { catalog = self.getShortXIconCatalog() || []; } catch(e) { safeLog(null, 'e', "catch " + String(e)); } if (!catalog.length) { - try { catalog = self.getShortXIconCatalog(true) || []; } catch(e) {} + try { catalog = self.getShortXIconCatalog(true) || []; } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } if (!catalog.length) { self.toast("\u56fe\u6807\u5e93\u672a\u52a0\u8f7d"); @@ -3949,9 +3959,9 @@ FloatBallAppWM.prototype.showShortXIconPickerPopup = function(opts) { function dismiss() { if (isDismissed) return; isDismissed = true; - try { wm.removeView(rootOverlay); } catch(e) {} + try { wm.removeView(rootOverlay); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } if (typeof onDismissCb === "function") { - try { onDismissCb(); } catch(eD) {} + try { onDismissCb(); } catch(eD) { safeLog(null, 'e', "catch " + String(eD)); } } } rootOverlay.setOnClickListener(new android.view.View.OnClickListener({ onClick: function() { dismiss(); } })); @@ -3976,7 +3986,7 @@ FloatBallAppWM.prototype.showShortXIconPickerPopup = function(opts) { var searchEt = new android.widget.EditText(context); searchEt.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 13); searchEt.setTextColor(textColor); - try { searchEt.setHintTextColor(subTextColor); } catch(e) {} + try { searchEt.setHintTextColor(subTextColor); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } searchEt.setHint("\u641c\u7d22\u56fe\u6807\u540d\uff0c\u5982 share / home"); searchEt.setSingleLine(true); searchEt.setPadding(self.dp(10), self.dp(8), self.dp(10), self.dp(8)); @@ -4025,7 +4035,7 @@ FloatBallAppWM.prototype.showShortXIconPickerPopup = function(opts) { btn.setTextColor(active ? C.primary : subTextColor); try { btn.setBackground(active ? self.ui.createRoundDrawable(self.withAlpha(C.primary, 0.15), self.dp(16)) : null); - } catch(e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } } refreshTabs(); @@ -4099,7 +4109,7 @@ FloatBallAppWM.prototype.showShortXIconPickerPopup = function(opts) { selectConfirm.setGravity(android.view.Gravity.CENTER); var pressedColor = self.withAlpha(C.primary, 0.8); selectConfirm.setBackground(self.ui.createRippleDrawable(C.primary, pressedColor, self.dp(24))); - try { selectConfirm.setElevation(self.dp(2)); } catch(e){} + try { selectConfirm.setElevation(self.dp(2)); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } selectConfirm.setOnClickListener(new android.view.View.OnClickListener({ onClick: function(v) { self.touchActivity(); @@ -4119,14 +4129,14 @@ FloatBallAppWM.prototype.showShortXIconPickerPopup = function(opts) { if (selectedName) { selectNameTv.setText(selectedName); var dr = null; - try { dr = self.getShortXIconDrawable(selectedName); } catch(e) {} + try { dr = self.getShortXIconDrawable(selectedName); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } if (dr) selectPreview.setImageDrawable(dr); else selectPreview.setImageDrawable(null); } else { selectNameTv.setText("\u672a\u9009\u62e9"); selectPreview.setImageDrawable(null); } - } catch(e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } updateSelectPreview(); @@ -4169,7 +4179,7 @@ FloatBallAppWM.prototype.showShortXIconPickerPopup = function(opts) { cell.setClickable(true); var bgColor = cardColor; - try { bgColor = self.withAlpha(cardColor, 0.96); } catch(e) {} + try { bgColor = self.withAlpha(cardColor, 0.96); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } cell.setBackground(self.ui.createRoundDrawable(bgColor, self.dp(10))); var iv = new android.widget.ImageView(context); @@ -4178,7 +4188,7 @@ FloatBallAppWM.prototype.showShortXIconPickerPopup = function(opts) { try { var dr = self.getShortXIconDrawable(item.name); if (dr) { iv.setImageDrawable(dr); } - } catch(e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } cell.addView(iv); var tv = new android.widget.TextView(context); @@ -4186,15 +4196,15 @@ FloatBallAppWM.prototype.showShortXIconPickerPopup = function(opts) { tv.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 10); tv.setGravity(android.view.Gravity.CENTER); tv.setMaxLines(1); - try { tv.setEllipsize(android.text.TextUtils.TruncateAt.END); } catch(e) {} + try { tv.setEllipsize(android.text.TextUtils.TruncateAt.END); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } tv.setPadding(self.dp(2), self.dp(2), self.dp(2), 0); cell.addView(tv); if (selectedName === item.name) { - try { cell.setBackground(self.ui.createRoundDrawable(self.withAlpha(C.primary, 0.2), self.dp(10))); } catch(e) {} - try { tv.setTextColor(C.primary); } catch(e) {} + try { cell.setBackground(self.ui.createRoundDrawable(self.withAlpha(C.primary, 0.2), self.dp(10))); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } + try { tv.setTextColor(C.primary); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } else { - try { tv.setTextColor(subTextColor); } catch(e) {} + try { tv.setTextColor(subTextColor); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } cell.setOnClickListener(new android.view.View.OnClickListener({ @@ -4257,7 +4267,7 @@ FloatBallAppWM.prototype.showColorPickerPopup = function(opts) { var c = self.ui.colors.accent; return "#" + ("00000000" + (c >>> 0).toString(16)).slice(-8); } - } catch(e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } return "#FF4081"; } @@ -4317,12 +4327,12 @@ FloatBallAppWM.prototype.showColorPickerPopup = function(opts) { if (rn) recentColors.push(rn); } } - } catch(eRecentLoad) {} + } catch(eRecentLoad) { safeLog(null, 'e', "catch " + String(eRecentLoad)); } function saveRecentColors() { try { self.savePanelState(RECENT_COLORS_KEY, { colors: recentColors.slice(0, MAX_RECENT_COLORS) }); - } catch(eRecentSave) {} + } catch(eRecentSave) { safeLog(null, 'e', "catch " + String(eRecentSave)); } } function pushRecentColor(hex) { @@ -4373,22 +4383,22 @@ FloatBallAppWM.prototype.showColorPickerPopup = function(opts) { try { var dr = null; if (currentIconName) { - try { dr = self.getShortXIconDrawable(currentIconName); } catch(e) {} + try { dr = self.getShortXIconDrawable(currentIconName); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } if (dr) { if (!isFollowTheme && selectedColor) { try { var parsed = android.graphics.Color.parseColor(selectedColor); dr.setColorFilter(parsed, android.graphics.PorterDuff.Mode.SRC_IN); - } catch(e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } else { - try { dr.clearColorFilter(); } catch(e) {} + try { dr.clearColorFilter(); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } previewIv.setImageDrawable(dr); } else { previewIv.setImageDrawable(null); } - } catch(e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } updatePreview(); @@ -4432,7 +4442,7 @@ FloatBallAppWM.prototype.showColorPickerPopup = function(opts) { lp.height = self.dp(28); lp.setMargins(margin, margin, margin, margin); cell.setLayoutParams(lp); - } catch(e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } var swatch = new android.view.View(context); swatch.setLayoutParams(new android.widget.FrameLayout.LayoutParams(android.widget.FrameLayout.LayoutParams.MATCH_PARENT, android.widget.FrameLayout.LayoutParams.MATCH_PARENT)); @@ -4441,7 +4451,7 @@ FloatBallAppWM.prototype.showColorPickerPopup = function(opts) { bg.setColor(android.graphics.Color.parseColor(hex)); bg.setCornerRadius(self.dp(5)); swatch.setBackground(bg); - } catch(e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } cell.addView(swatch); if (selectedColor === hex) { @@ -4451,7 +4461,7 @@ FloatBallAppWM.prototype.showColorPickerPopup = function(opts) { border.setCornerRadius(self.dp(5)); border.setStroke(self.dp(2), C.primary); cell.setForeground(border); - } catch(e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } cell.setOnClickListener(new android.view.View.OnClickListener({ @@ -4471,7 +4481,7 @@ FloatBallAppWM.prototype.showColorPickerPopup = function(opts) { recentGrid.addView(cell); })(recentColors[ri]); } - } catch(e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } refreshRecentGrid(); @@ -4497,7 +4507,7 @@ FloatBallAppWM.prototype.showColorPickerPopup = function(opts) { lp.height = self.dp(32); lp.setMargins(margin, margin, margin, margin); cell.setLayoutParams(lp); - } catch(e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } var swatch = new android.view.View(context); swatch.setLayoutParams(new android.widget.FrameLayout.LayoutParams(android.widget.FrameLayout.LayoutParams.MATCH_PARENT, android.widget.FrameLayout.LayoutParams.MATCH_PARENT)); @@ -4506,7 +4516,7 @@ FloatBallAppWM.prototype.showColorPickerPopup = function(opts) { bg.setColor(android.graphics.Color.parseColor(hex)); bg.setCornerRadius(self.dp(6)); swatch.setBackground(bg); - } catch(e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } cell.addView(swatch); if (selectedColor === hex) { @@ -4516,7 +4526,7 @@ FloatBallAppWM.prototype.showColorPickerPopup = function(opts) { border.setCornerRadius(self.dp(6)); border.setStroke(self.dp(3), C.primary); cell.setForeground(border); - } catch(e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } cell.setOnClickListener(new android.view.View.OnClickListener({ @@ -4545,7 +4555,7 @@ FloatBallAppWM.prototype.showColorPickerPopup = function(opts) { for (i = 0; i < count; i++) { var cell = commonGrid.getChildAt(i); if (!cell) continue; - try { cell.setForeground(null); } catch(e) {} + try { cell.setForeground(null); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } var idx = commonTintHexValues.indexOf(selectedColor); if (idx >= 0 && idx < count) { @@ -4557,10 +4567,10 @@ FloatBallAppWM.prototype.showColorPickerPopup = function(opts) { border.setCornerRadius(self.dp(6)); border.setStroke(self.dp(3), C.primary); matchedCell.setForeground(border); - } catch(e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } } - } catch(e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } // 颜色值显示 @@ -4644,7 +4654,7 @@ FloatBallAppWM.prototype.showColorPickerPopup = function(opts) { rgbValTvs[0].setText(String(initR)); rgbValTvs[1].setText(String(initG)); rgbValTvs[2].setText(String(initB)); - } catch(e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } syncRgbSeeks(); diff --git a/code/th_15_extra.js b/code/th_15_extra.js index c09f98e..a62f06e 100644 --- a/code/th_15_extra.js +++ b/code/th_15_extra.js @@ -16,7 +16,7 @@ FloatBallAppWM.prototype.buildViewerPanelView = function(titleText, bodyText) { bgDr.setColor(bgColor); bgDr.setCornerRadius(this.dp(16)); panel.setBackground(bgDr); - try { panel.setElevation(this.dp(8)); } catch(e){} + try { panel.setElevation(this.dp(8)); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } panel.setPadding( this.dp(16), @@ -39,8 +39,8 @@ FloatBallAppWM.prototype.buildViewerPanelView = function(titleText, bodyText) { panel.addView(sep); var scroll = new android.widget.ScrollView(context); - try { scroll.setOverScrollMode(android.view.View.OVER_SCROLL_NEVER); } catch (eOS) {} - try { scroll.setVerticalScrollBarEnabled(true); } catch (eSB) {} + try { scroll.setOverScrollMode(android.view.View.OVER_SCROLL_NEVER); } catch(eOS) { safeLog(null, 'e', "catch " + String(eOS)); } + try { scroll.setVerticalScrollBarEnabled(true); } catch(eSB) { safeLog(null, 'e', "catch " + String(eSB)); } // 给内容加一点边距 var contentBox = new android.widget.LinearLayout(context); @@ -53,11 +53,11 @@ FloatBallAppWM.prototype.buildViewerPanelView = function(titleText, bodyText) { tv.setTextColor(codeColor); tv.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, Number(this.config.CONTENT_VIEWER_TEXT_SP || 12)); // 增加行距优化阅读 - try { tv.setLineSpacing(this.dp(4), 1.0); } catch(eLS) {} + try { tv.setLineSpacing(this.dp(4), 1.0); } catch(eLS) { safeLog(null, 'e', "catch " + String(eLS)); } // 使用等宽字体显示代码/日志 - try { tv.setTypeface(android.graphics.Typeface.MONOSPACE); } catch(eTF) {} + try { tv.setTypeface(android.graphics.Typeface.MONOSPACE); } catch(eTF) { safeLog(null, 'e', "catch " + String(eTF)); } // WindowManager 环境下禁用文本选择,否则长按/选择会因缺少 Token 崩溃 - try { tv.setTextIsSelectable(false); } catch (eSel) {} + try { tv.setTextIsSelectable(false); } catch(eSel) { safeLog(null, 'e', "catch " + String(eSel)); } contentBox.addView(tv); @@ -96,7 +96,7 @@ FloatBallAppWM.prototype.buildPanelView = function(panelType) { bgDr.setColor(this.withAlpha(bgColor, this.config.PANEL_BG_ALPHA)); bgDr.setCornerRadius(this.dp(16)); panel.setBackground(bgDr); - try { panel.setElevation(this.dp(8)); } catch(e){} + try { panel.setElevation(this.dp(8)); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } var padDp = this.config.PANEL_PADDING_DP; panel.setPadding( @@ -149,9 +149,9 @@ FloatBallAppWM.prototype.buildPanelView = function(panelType) { } var scroll = new android.widget.ScrollView(context); - try { scroll.setOverScrollMode(android.view.View.OVER_SCROLL_NEVER); } catch (eOS) {} - try { scroll.setVerticalScrollBarEnabled(false); } catch (eSB) {} - try { scroll.setFillViewport(true); } catch (eFV) {} + try { scroll.setOverScrollMode(android.view.View.OVER_SCROLL_NEVER); } catch(eOS) { safeLog(null, 'e', "catch " + String(eOS)); } + try { scroll.setVerticalScrollBarEnabled(false); } catch(eSB) { safeLog(null, 'e', "catch " + String(eSB)); } + try { scroll.setFillViewport(true); } catch(eFV) { safeLog(null, 'e', "catch " + String(eFV)); } var scrollLp = new android.widget.LinearLayout.LayoutParams(contentW, scrollH); scroll.setLayoutParams(scrollLp); @@ -170,7 +170,7 @@ FloatBallAppWM.prototype.buildPanelView = function(panelType) { // var totalCells = totalBtns > minCells ? totalBtns : minCells; var rowCount = Math.ceil(totalCells / cols2); - try { grid.setRowCount(rowCount); } catch (eRC) {} + try { grid.setRowCount(rowCount); } catch(eRC) { safeLog(null, 'e', "catch " + String(eRC)); } grid.setOnTouchListener(new JavaAdapter(android.view.View.OnTouchListener, { onTouch: function(v, e) { self.touchActivity(); return false; } @@ -193,7 +193,7 @@ FloatBallAppWM.prototype.buildPanelView = function(panelType) { // 单元格背景:如果是有功能的按钮,给个卡片背景;否则透明 if (btnCfg) { cell.setBackground(self.ui.createRoundDrawable(cardColor, self.dp(12))); - try { cell.setElevation(self.dp(2)); } catch(e){} + try { cell.setElevation(self.dp(2)); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } else { // 空格子占位 } @@ -206,7 +206,7 @@ FloatBallAppWM.prototype.buildPanelView = function(panelType) { // 但 resolveIconDrawable 逻辑比较复杂,这里暂时不强制染色,除非用户配置了 TINT if (!isDark && btnCfg && !btnCfg.type && !btnCfg.pkg) { // 简单的系统图标在亮色模式下可能看不清,染成深色 - try { iv.setColorFilter(C.textPriLight, android.graphics.PorterDuff.Mode.SRC_IN); } catch(eCF){} + try { iv.setColorFilter(C.textPriLight, android.graphics.PorterDuff.Mode.SRC_IN); } catch(eCF) { safeLog(null, 'e', "catch " + String(eCF)); } } } @@ -224,7 +224,7 @@ FloatBallAppWM.prototype.buildPanelView = function(panelType) { tv.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, this.config.PANEL_LABEL_TEXT_SIZE_SP); tv.setTextColor(textColor); tv.setGravity(android.view.Gravity.CENTER); - try { tv.setLines(1); tv.setEllipsize(android.text.TextUtils.TruncateAt.END); } catch(eL){} + try { tv.setLines(1); tv.setEllipsize(android.text.TextUtils.TruncateAt.END); } catch(eL) { safeLog(null, 'e', "catch " + String(eL)); } var tvLp = new android.widget.LinearLayout.LayoutParams( android.widget.LinearLayout.LayoutParams.MATCH_PARENT, // 宽度填满,方便居中 @@ -251,8 +251,8 @@ FloatBallAppWM.prototype.buildPanelView = function(panelType) { })); })(i, btnCfg); } else { - try { iv.setAlpha(0); } catch (eA0) {} - try { cell.setClickable(false); } catch (eC0) {} + try { iv.setAlpha(0); } catch(eA0) { safeLog(null, 'e', "catch " + String(eA0)); } + try { cell.setClickable(false); } catch(eC0) { safeLog(null, 'e', "catch " + String(eC0)); } } grid.addView(cell); @@ -460,7 +460,7 @@ FloatBallAppWM.prototype.addPanel = function(panel, x, y, which) { panel.setScaleY(1); panel.setAlpha(1); } - } catch (eA) {} + } catch(eA) { safeLog(null, 'e', "catch " + String(eA)); } // # 日志防抖:5秒内相同面板类型不重复记录 var now = Date.now(); @@ -516,8 +516,8 @@ FloatBallAppWM.prototype.showPanelAvoidBall = function(which) { // 需要处理 newPanel 的 LayoutParams var contentLp = new android.widget.LinearLayout.LayoutParams(-1, 0); contentLp.weight = 1; - try { newPanel.setBackground(null); } catch(e){} // 移除背景,使用 Container 背景 - try { newPanel.setElevation(0); } catch(e){} + try { newPanel.setBackground(null); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } // 移除背景,使用 Container 背景 + try { newPanel.setElevation(0); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } newPanel.setLayoutParams(contentLp); container.addView(newPanel); @@ -651,7 +651,7 @@ FloatBallAppWM.prototype.showPanelAvoidBall = function(which) { self.touchActivity(); } catch (e) { if (self.L) self.L.e("showPanelAvoidBall callback err=" + String(e)); - try { self.toast("面板显示失败: " + String(e)); } catch (et) {} + try { self.toast("面板显示失败: " + String(e)); } catch(et) { safeLog(null, 'e', "catch " + String(et)); } } }; @@ -691,7 +691,7 @@ FloatBallAppWM.prototype.wrapDraggablePanel = function(contentView, optionsOrTit bgDr.setColor(isDark ? C.bgDark : C.bgLight); bgDr.setCornerRadius(this.dp(12)); container.setBackground(bgDr); - try { container.setElevation(this.dp(8)); } catch(e){} + try { container.setElevation(this.dp(8)); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } // Header var header = new android.widget.LinearLayout(context); @@ -717,7 +717,7 @@ FloatBallAppWM.prototype.wrapDraggablePanel = function(contentView, optionsOrTit else self.hideAllPanels(); }); btnClose.setPadding(self.dp(8), self.dp(4), self.dp(8), self.dp(4)); - try { btnClose.setElevation(this.dp(25)); } catch(e){} // Ensure on top of resize handles + try { btnClose.setElevation(this.dp(25)); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } // Ensure on top of resize handles header.addView(btnClose); // Spacer to avoid overlap with Top-Right resize handle @@ -733,8 +733,8 @@ FloatBallAppWM.prototype.wrapDraggablePanel = function(contentView, optionsOrTit // Add Content // 移除 content 原有的背景和 elevation,避免重复 - try { contentView.setBackground(null); } catch(e){} - try { contentView.setElevation(0); } catch(e){} + try { contentView.setBackground(null); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } + try { contentView.setElevation(0); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } var contentLp = new android.widget.LinearLayout.LayoutParams(-1, 0); contentLp.weight = 1; @@ -746,7 +746,7 @@ FloatBallAppWM.prototype.wrapDraggablePanel = function(contentView, optionsOrTit // Resize Handle (Bottom-Right Corner) - Invisible var handleBR = new android.view.View(context); - try { handleBR.setElevation(this.dp(20)); } catch(e){} + try { handleBR.setElevation(this.dp(20)); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } var handleBRLp = new android.widget.FrameLayout.LayoutParams(this.dp(30), this.dp(30)); handleBRLp.gravity = android.view.Gravity.BOTTOM | android.view.Gravity.END; handleBRLp.rightMargin = 0; @@ -755,7 +755,7 @@ FloatBallAppWM.prototype.wrapDraggablePanel = function(contentView, optionsOrTit // Resize Handle (Bottom-Left Corner) - Invisible var handleBL = new android.view.View(context); - try { handleBL.setElevation(this.dp(20)); } catch(e){} + try { handleBL.setElevation(this.dp(20)); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } var handleBLLp = new android.widget.FrameLayout.LayoutParams(this.dp(30), this.dp(30)); handleBLLp.gravity = android.view.Gravity.BOTTOM | android.view.Gravity.START; handleBLLp.bottomMargin = 0; @@ -764,7 +764,7 @@ FloatBallAppWM.prototype.wrapDraggablePanel = function(contentView, optionsOrTit // Resize Handle (Top-Left Corner) - Invisible var handleTL = new android.view.View(context); - try { handleTL.setElevation(this.dp(20)); } catch(e){} + try { handleTL.setElevation(this.dp(20)); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } var handleTLLp = new android.widget.FrameLayout.LayoutParams(this.dp(30), this.dp(30)); handleTLLp.gravity = android.view.Gravity.TOP | android.view.Gravity.START; handleTLLp.topMargin = 0; @@ -773,7 +773,7 @@ FloatBallAppWM.prototype.wrapDraggablePanel = function(contentView, optionsOrTit // Resize Handle (Top-Right Corner) - Invisible var handleTR = new android.view.View(context); - try { handleTR.setElevation(this.dp(20)); } catch(e){} + try { handleTR.setElevation(this.dp(20)); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } var handleTRLp = new android.widget.FrameLayout.LayoutParams(this.dp(30), this.dp(30)); handleTRLp.gravity = android.view.Gravity.TOP | android.view.Gravity.END; handleTRLp.topMargin = 0; @@ -867,7 +867,7 @@ FloatBallAppWM.prototype.attachDragResizeListeners = function(rootView, headerVi lp.x = targetX; lp.y = targetY; - try { wm.updateViewLayout(rootView, lp); } catch(e){} + try { wm.updateViewLayout(rootView, lp); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } } return true; @@ -938,10 +938,10 @@ FloatBallAppWM.prototype.attachDragResizeListeners = function(rootView, headerVi lpCur.height = initialH; lpCur.x = initialX; lpCur.y = initialY; - try { wm.updateViewLayout(rootView, lpCur); } catch(e){} + try { wm.updateViewLayout(rootView, lpCur); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } resizing = true; - } catch(e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } }); self.state.h.postDelayed(longPressRunnable, 300); // 300ms hold to activate resize @@ -1022,7 +1022,7 @@ FloatBallAppWM.prototype.attachDragResizeListeners = function(rootView, headerVi lp.y = Math.round(newY); } - try { wm.updateViewLayout(rootView, lp); } catch(e){} + try { wm.updateViewLayout(rootView, lp); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } } return true; @@ -1138,7 +1138,7 @@ FloatBallAppWM.prototype.showViewerPanel = function(title, text) { }; FloatBallAppWM.prototype.cancelLongPressTimer = function() { - try { if (this.state.longPressRunnable && this.state.h) this.state.h.removeCallbacks(this.state.longPressRunnable); } catch (e) {} + try { if (this.state.longPressRunnable && this.state.h) this.state.h.removeCallbacks(this.state.longPressRunnable); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } this.state.longPressArmed = false; this.state.longPressRunnable = null; }; @@ -1208,7 +1208,7 @@ FloatBallAppWM.prototype.setupTouchListener = function() { self.touchActivity(); // 恢复不透明度 - try { v.setAlpha(1.0); } catch(eA) {} + try { v.setAlpha(1.0); } catch(eA) { safeLog(null, 'e', "catch " + String(eA)); } if (self.state.docked) { self.undockToFull(false, null); @@ -1224,14 +1224,14 @@ FloatBallAppWM.prototype.setupTouchListener = function() { lastTouchX = e.getRawX(); lastTouchY = e.getRawY(); - try { v.setPressed(true); } catch (eP) {} - try { v.drawableHotspotChanged(e.getX(), e.getY()); } catch (eH) {} + try { v.setPressed(true); } catch(eP) { safeLog(null, 'e', "catch " + String(eP)); } + try { v.drawableHotspotChanged(e.getX(), e.getY()); } catch(eH) { safeLog(null, 'e', "catch " + String(eH)); } // 按下缩小反馈 if (self.config.ENABLE_ANIMATIONS) { try { v.animate().scaleX(0.9).scaleY(0.9).setDuration(100).start(); - } catch(eS){} + } catch(eS) { safeLog(null, 'e', "catch " + String(eS)); } } self.armLongPress(); @@ -1268,11 +1268,11 @@ FloatBallAppWM.prototype.setupTouchListener = function() { self.state.ballLp.y = self.clamp(self.state.ballLp.y, 0, self.state.screen.h - di.ballSize); self.state.ballLp.width = di.ballSize; - try { self.state.ballContent.setX(0); } catch (e0) {} + try { self.state.ballContent.setX(0); } catch(e0) { safeLog(null, 'e', "catch " + String(e0)); } var now = java.lang.System.currentTimeMillis(); if (now - lastUpdateTs > 10) { // 10ms 节流 - try { self.state.wm.updateViewLayout(self.state.ballRoot, self.state.ballLp); } catch (eU) {} + try { self.state.wm.updateViewLayout(self.state.ballRoot, self.state.ballLp); } catch(eU) { safeLog(null, 'e', "catch " + String(eU)); } lastUpdateTs = now; } @@ -1286,16 +1286,16 @@ FloatBallAppWM.prototype.setupTouchListener = function() { if (a === android.view.MotionEvent.ACTION_UP || a === android.view.MotionEvent.ACTION_CANCEL) { self.touchActivity(); - try { v.setPressed(false); } catch (eP2) {} + try { v.setPressed(false); } catch(eP2) { safeLog(null, 'e', "catch " + String(eP2)); } self.cancelLongPressTimer(); // 恢复缩放 if (self.config.ENABLE_ANIMATIONS) { try { v.animate().scaleX(1.0).scaleY(1.0).setDuration(150).start(); - } catch(eS){} + } catch(eS) { safeLog(null, 'e', "catch " + String(eS)); } } else { - try { v.setScaleX(1); v.setScaleY(1); } catch(eS){} + try { v.setScaleX(1); v.setScaleY(1); } catch(eS) { safeLog(null, 'e', "catch " + String(eS)); } } if (self.state.longPressTriggered) { @@ -1305,7 +1305,7 @@ FloatBallAppWM.prototype.setupTouchListener = function() { } if (!self.state.dragging && a === android.view.MotionEvent.ACTION_UP) { - try { self.playBounce(v); } catch (eB) {} + try { self.playBounce(v); } catch(eB) { safeLog(null, 'e', "catch " + String(eB)); } if (self.state.addedPanel) self.hideMainPanel(); else self.showPanelAvoidBall("main"); @@ -1315,7 +1315,7 @@ FloatBallAppWM.prototype.setupTouchListener = function() { } else { // 拖拽结束 // 确保最后位置被更新 - try { self.state.wm.updateViewLayout(self.state.ballRoot, self.state.ballLp); } catch (eU) {} + try { self.state.wm.updateViewLayout(self.state.ballRoot, self.state.ballLp); } catch(eU) { safeLog(null, 'e', "catch " + String(eU)); } var forceSide = null; // 计算速度 @@ -1360,7 +1360,7 @@ FloatBallAppWM.prototype.createBallViews = function() { var root = new android.widget.FrameLayout(context); root.setClipToPadding(true); root.setClipChildren(true); - try { root.setElevation(this.dp(6)); } catch(e){} + try { root.setElevation(this.dp(6)); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } var content = new android.widget.FrameLayout(context); var lp = new android.widget.FrameLayout.LayoutParams(di.ballSize, di.ballSize); @@ -1419,7 +1419,7 @@ try { } else { safeLog(this.L, 'w', "Ball icon file load failed: " + iconFilePath); } - } catch (eF) {} + } catch(eF) { safeLog(null, 'e', "catch " + String(eF)); } } // # 2) app:加载应用图标 (file 失败也会尝试 app) @@ -1434,7 +1434,7 @@ try { usedKind = "app"; } } - } catch (eA) {} + } catch(eA) { safeLog(null, 'e', "catch " + String(eA)); } } // # 2.5) shortx:专门加载 ShortX 内置图标(也作为 file 模式的兜底) @@ -1455,7 +1455,7 @@ try { safeLog(this.L, 'i', "File icon failed, fallback to shortx icon"); } } - } catch (eShortx2) {} + } catch(eShortx2) { safeLog(null, 'e', "catch " + String(eShortx2)); } } // # 3) android:或所有兜底,走资源 id(优先尝试 ShortX 内置图标) @@ -1469,13 +1469,13 @@ try { if (usedDrawable != null) { usedKind = "shortx"; } - } catch (eShortx) {} + } catch(eShortx) { safeLog(null, 'e', "catch " + String(eShortx)); } } if (usedDrawable != null) { iv.setImageDrawable(usedDrawable); } else if (iconResId > 0) { - try { iv.setImageResource(iconResId); usedKind = "android"; } catch (eR) {} + try { iv.setImageResource(iconResId); usedKind = "android"; } catch(eR) { safeLog(null, 'e', "catch " + String(eR)); } } else { // # 没有任何可用图标,直接不加到布局 usedKind = "none"; @@ -1505,11 +1505,11 @@ try { try { var tintColor2 = android.graphics.Color.parseColor(tintHex); iv.setColorFilter(tintColor2, android.graphics.PorterDuff.Mode.SRC_IN); - } catch (eTint2) {} + } catch(eTint2) { safeLog(null, 'e', "catch " + String(eTint2)); } } else if (usedKind === "android") { - try { iv.setColorFilter(android.graphics.Color.WHITE, android.graphics.PorterDuff.Mode.SRC_IN); } catch (eCF) {} + try { iv.setColorFilter(android.graphics.Color.WHITE, android.graphics.PorterDuff.Mode.SRC_IN); } catch(eCF) { safeLog(null, 'e', "catch " + String(eCF)); } } else { - try { iv.clearColorFilter(); } catch (eCL) {} + try { iv.clearColorFilter(); } catch(eCL) { safeLog(null, 'e', "catch " + String(eCL)); } } box.addView(iv); @@ -1518,7 +1518,7 @@ try { content.addView(box); } -} catch (eBallInner) {} + } catch(eBallInner) { safeLog(null, 'e', "catch " + String(eBallInner)); } this.updateBallContentBackground(content); @@ -1526,7 +1526,7 @@ try { // # 阴影控制:file/app 模式下不加阴影(避免透明背景带黑框) var _uk = this.state.usedIconKind; if (_uk !== "file" && _uk !== "app") { - try { root.setElevation(this.dp(6)); } catch(e){} + try { root.setElevation(this.dp(6)); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } content.setClickable(true); diff --git a/code/th_16_entry.js b/code/th_16_entry.js index 8a478ea..0541235 100644 --- a/code/th_16_entry.js +++ b/code/th_16_entry.js @@ -7,7 +7,7 @@ function runOnMainSync(fn, timeoutMs) { if (mainLooper !== null && myLooper !== null && myLooper === mainLooper) { return { ok: true, value: fn() }; } - } catch (eLoop) {} + } catch(eLoop) { safeLog(null, 'e', "catch " + String(eLoop)); } try { var box = { ok: false, value: null, error: null }; @@ -76,9 +76,17 @@ FloatBallAppWM.prototype.close = function() { this.cancelDockTimer(); this.stopDisplayMonitor(); + // # 取消正在进行的球体动画 + try { + if (this.state.ballAnimator) { + this.state.ballAnimator.cancel(); + this.state.ballAnimator = null; + } + } catch(eAnim) { safeLog(null, 'e', "catch " + String(eAnim)); } + try { if (this.state.addedBall && this.state.ballLp) this.savePos(this.state.ballLp.x, this.state.ballLp.y); - } catch (eS) {} + } catch(eS) { safeLog(null, 'e', "catch " + String(eS)); } try { FileIO.flushDebouncedWrites(); } catch (eFlushCfg) { safeLog(this.L, 'e', "flushDebouncedWrites fail: " + String(eFlushCfg)); } this.hideAllPanels(); @@ -109,7 +117,7 @@ FloatBallAppWM.prototype.close = function() { if (android.os.Build.VERSION.SDK_INT >= 18) this.state.ht.quitSafely(); else this.state.ht.quit(); } - } catch (eQ) {} + } catch(eQ) { safeLog(null, 'e', "catch " + String(eQ)); } // # 清理图标加载线程 try { @@ -117,14 +125,14 @@ FloatBallAppWM.prototype.close = function() { if (android.os.Build.VERSION.SDK_INT >= 18) this._iconLoader.ht.quitSafely(); else this._iconLoader.ht.quit(); } - } catch (eIcon) {} + } catch(eIcon) { safeLog(null, 'e', "catch " + String(eIcon)); } try { if (self.__scIconLoaderSingleton && self.__scIconLoaderSingleton.ht) { if (android.os.Build.VERSION.SDK_INT >= 18) self.__scIconLoaderSingleton.ht.quitSafely(); else self.__scIconLoaderSingleton.ht.quit(); } - } catch (eScIcon) {} - try { self.__scIconLoaderSingleton = null; } catch (eScIcon2) {} + } catch(eScIcon) { safeLog(null, 'e', "catch " + String(eScIcon)); } + try { self.__scIconLoaderSingleton = null; } catch(eScIcon2) { safeLog(null, 'e', "catch " + String(eScIcon2)); } safeLog(this.L, 'i', "close done"); @@ -137,7 +145,7 @@ FloatBallAppWM.prototype.close = function() { this.L._flushTimer = null; } } - } catch (eLog) {} + } catch(eLog) { safeLog(null, 'e', "catch " + String(eLog)); } // # 清空缓存 try { @@ -145,7 +153,7 @@ FloatBallAppWM.prototype.close = function() { this._shortcutIconFailTs = {}; if (typeof __scIconCache !== "undefined") __scIconCache = {}; if (typeof __scAppLabelCache !== "undefined") __scAppLabelCache = {}; - } catch (eCache) {} + } catch(eCache) { safeLog(null, 'e', "catch " + String(eCache)); } }; /** @@ -161,7 +169,7 @@ FloatBallAppWM.prototype.dispose = function() { if (self.__shortcutPickerSingleton === this.__shortcutPickerSingleton) { self.__shortcutPickerSingleton = null; } - } catch (e) {} + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } // # 清理配置缓存 this._settingsCache = null; @@ -196,7 +204,17 @@ FloatBallAppWM.prototype.startAsync = function(entryProcInfo, closeRule) { shell("am broadcast -a " + String(this.config.ACTION_CLOSE_ALL)); preCloseSent = true; } - } catch (e1) {} + } catch(e1) { safeLog(null, 'e', "catch " + String(e1)); } + } + + // # 清理旧的 HandlerThread,防止重复启动导致线程泄漏 + if (this.state.ht) { + try { + if (android.os.Build.VERSION.SDK_INT >= 18) this.state.ht.quitSafely(); + else this.state.ht.quit(); + } catch(eOldHt) { safeLog(null, 'e', "catch " + String(eOldHt)); } + this.state.ht = null; + this.state.h = null; } var ht = new android.os.HandlerThread(String(this.config.WM_THREAD_NAME)); @@ -211,9 +229,9 @@ FloatBallAppWM.prototype.startAsync = function(entryProcInfo, closeRule) { var closeRcv = registerReceiverOnMain(this.config.ACTION_CLOSE_ALL, function(ctx, it) { try { h.post(new JavaAdapter(java.lang.Runnable, { - run: function() { try { self.close(); } catch (e1) {} } + run: function() { try { self.close(); } catch(e1) { safeLog(null, 'e', "catch " + String(e1)); } } })); - } catch (e2) {} + } catch(e2) { safeLog(null, 'e', "catch " + String(e2)); } }); if (closeRcv) this.state.receivers.push(closeRcv); @@ -237,10 +255,10 @@ FloatBallAppWM.prototype.startAsync = function(entryProcInfo, closeRule) { if (self.state.panel) self.updatePanelBackground(self.state.panel); if (self.state.settingsPanel) self.updatePanelBackground(self.state.settingsPanel); if (self.state.viewerPanel) self.updatePanelBackground(self.state.viewerPanel); - } catch (e1) {} + } catch(e1) { safeLog(null, 'e', "catch " + String(e1)); } } })); - } catch (e0) {} + } catch(e0) { safeLog(null, 'e', "catch " + String(e0)); } } ); if (cfgRcv) this.state.receivers.push(cfgRcv); @@ -265,10 +283,10 @@ FloatBallAppWM.prototype.startAsync = function(entryProcInfo, closeRule) { self.state.wm.addView(self.state.ballRoot, self.state.ballLp); self.state.addedBall = true; } catch (eAdd) { - try { self.toast("悬浮球 addView 失败: " + String(eAdd)); } catch (eT) {} + try { self.toast("悬浮球 addView 失败: " + String(eAdd)); } catch(eT) { safeLog(null, 'e', "catch " + String(eT)); } if (self.L) self.L.fatal("addView ball fail err=" + String(eAdd)); self.state.addedBall = false; - try { self.close(); } catch (eC) {} + try { self.close(); } catch(eC) { safeLog(null, 'e', "catch " + String(eC)); } return; } @@ -280,9 +298,9 @@ FloatBallAppWM.prototype.startAsync = function(entryProcInfo, closeRule) { self.L.i("ball x=" + String(self.state.ballLp.x) + " y=" + String(self.state.ballLp.y) + " sizeDp=" + String(self.config.BALL_SIZE_DP)); } } catch (eAll) { - try { self.toast("启动异常: " + String(eAll)); } catch (eTT2) {} + try { self.toast("启动异常: " + String(eAll)); } catch(eTT2) { safeLog(null, 'e', "catch " + String(eTT2)); } if (self.L) self.L.fatal("start runnable err=" + String(eAll)); - try { self.close(); } catch (eC2) {} + try { self.close(); } catch(eC2) { safeLog(null, 'e', "catch " + String(eC2)); } } } }));