前面幾天一直在加新功能,結果累積了不少 bug。今天暫停開發新功能,專心修 bug 讓工具更穩定。
最常遇到的問題是操作到一半裝置突然斷線:
// 每次操作前檢查裝置是否還在
async checkDeviceConnection(deviceId) {
try {
const devices = await this.getDevices();
return devices.some(d => d.id === deviceId);
} catch (error) {
return false;
}
}
async safeExecute(deviceId, operation) {
if (!await this.checkDeviceConnection(deviceId)) {
mdui.snackbar({ message: '裝置已斷線,請重新連接' });
this.resetUI();
return;
}
await operation();
}
發現工具開久了會越來越慢,原來是沒有清理事件監聽:
class DeviceManager {
constructor() {
this.polling = null;
}
startPolling() {
this.polling = setInterval(() => {
this.updateDeviceList();
}, 3000);
}
stopPolling() {
if (this.polling) {
clearInterval(this.polling);
this.polling = null;
}
}
// 視窗關閉時清理
cleanup() {
this.stopPolling();
// 清理其他資源...
}
}
有些 APP 名稱包含特殊字元,顯示會亂碼:
// 統一用 UTF-8 編碼處理
async executeCommand(cmd) {
return new Promise((resolve, reject) => {
exec(cmd, { encoding: 'utf8' }, (error, stdout, stderr) => {
if (error) {
reject(error);
return;
}
resolve(stdout);
});
});
}
一次刪除太多 APP 時介面會卡住,改成非同步處理:
async deleteSelectedApps() {
const selected = this.getSelectedApps();
for (let i = 0; i < selected.length; i++) {
const app = selected[i];
// 更新進度
this.updateProgress(i + 1, selected.length);
try {
await this.deleteWithBackup(this.deviceId, app.package);
// 讓主執行緒有時間更新 UI
await this.sleep(100);
} catch (error) {
console.error(`刪除 ${app.name} 失敗:`, error);
}
}
}
sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
原本的錯誤訊息都是英文,改成中文而且更友善:
handleError(error) {
let message = '操作失敗';
if (error.message.includes('device not found')) {
message = '找不到裝置,請檢查連接';
} else if (error.message.includes('permission denied')) {
message = '權限不足,請確認已開啟 USB 偵錯';
} else if (error.message.includes('not installed')) {
message = '此應用程式不存在';
}
mdui.snackbar({
message: message,
action: '查看詳情',
onActionClick: () => this.showErrorDetails(error)
});
}
在 Windows 上路徑處理有問題,統一用 path 模組:
// 錯誤寫法
const apkPath = backupDir + '/' + packageName + '.apk';
// 正確寫法
const apkPath = path.join(backupDir, `${packageName}.apk`);
方便之後除錯,把錯誤都記錄下來:
logError(error, context) {
const logPath = path.join(app.getPath('userData'), 'error.log');
const timestamp = new Date().toISOString();
const logEntry = `[${timestamp}] ${context}: ${error.message}\n${error.stack}\n\n`;
fs.appendFileSync(logPath, logEntry);
}