在一個基於 Android 的簡易計算器 Demo 中,點擊「Del」(刪除)按鈕時應用程式發生閃退。代碼邏輯為在 onClick 中處理 R.id.button_del 事件,嘗試通過 substring 移除輸入框最後一個字符。
查看 getResult() 及 onClick 中的字符串處理邏輯,發現以下隱患:
et.getText().toString() != "" 應使用 !str.isEmpty() 或 str.length() > 0,字符串比較應用 equals。str.substring(0, str.length()-1) 的終止索引可能為 -1,導致 StringIndexOutOfBoundsException。getResult() 中假設輸入格式固定為「數字 運算符 數字」(含空格),若用戶輸入不規範(如連續運算符、負數、小數點多次),indexOf(" ") 返回 -1 導致後續 substring 參數為負數,同樣拋出異常。重點修正 onClick 中 Del 邏輯及 getResult 的健壯性:
case R.id.button_del:
String currentText = et.getText().toString();
if (!currentText.isEmpty()) {
// 安全截取:長度至少為 1 時才執行
et.setText(currentText.substring(0, currentText.length() - 1));
}
break;
// 建議將 getResult 重構為更健壯的表達式解析器,或至少加入異常捕獲
private void getResult() {
String edt = et.getText().toString().trim();
if (edt.isEmpty()) return;
try {
// 簡易示例:使用 ScriptEngine 或第三方庫 (如 exp4j) 替代手寫解析
// 此處保留原邏輯但加入防護
if (!edt.contains(" ")) {
// 單純數字,無需計算
return;
}
// ... 原有解析邏輯,建議包裹在 try-catch 中
} catch (Exception e) {
et.setText("Error");
e.printStackTrace();
}
}
TextWatcher 實時監聽輸入,限制非法字符。ScriptEngineManager (JavaScript 引擎) 或 exp4j 庫處理數學表達式,避免手寫解析器的邊界情況 Bug。ViewBinding 或 DataBinding 替代大量 findViewById,減少樣板代碼。