首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Android 計算器 Demo 中 Del 按鈕導致閃退的數組越界修復

     編輯:程式設計綜合問答

問題現象

在一個基於 Android 的簡易計算器 Demo 中,點擊「Del」(刪除)按鈕時應用程式發生閃退。代碼邏輯為在 onClick 中處理 R.id.button_del 事件,嘗試通過 substring 移除輸入框最後一個字符。

錯誤分析

查看 getResult() 及 onClick 中的字符串處理邏輯,發現以下隱患:

  1. 空字符串判斷錯誤:et.getText().toString() != "" 應使用 !str.isEmpty() 或 str.length() > 0,字符串比較應用 equals。
  2. substring 索引越界:當輸入框為空或僅有一個字符時,str.substring(0, str.length()-1) 的終止索引可能為 -1,導致 StringIndexOutOfBoundsException。
  3. 運算符解析脆弱: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,減少樣板代碼。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved