0

在我的應用程序中,我想跟蹤EditText中的輸入。每個用戶在EditText修改一個字符一次我要追蹤:TextWatcher中的IndexOutOfBoundsException

  1. 如果加入一個字符/刪除
  2. 在/從中添加字符/刪除
  3. 是什麼性質的指數添加/刪除

我使用TextWatcher爲了實現這一點。我的方法一直工作到現在。但最近我在我的產品應用程序中發生了3次與IndexOutOfBoundsException的崩潰。我注意到的一件事是所有的崩潰發生在OS版本6.0.1的Galaxy S7上。

我想找出理解和解決這個崩潰的好方法。請參考以下

public class EditTextMonitor extends Activity implements TextWatcher { 
    private EditText etInputText; 

    private int deleteCharIndex = -1, addCharIndex = -1; 
    private char deleteChar; 
    private boolean wasCharDeleted; 
    private String prevCharSeq = ""; 

    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.mylayout); 
     etInputText = (EditText) findViewById(R.id.etInputText); 
    } 

    // Add TextChangedListener here to prevent call to text watcher methods upon switching 
    // orientation 
    protected void onPostCreate(Bundle savedInstanceState) { 
     super.onPostCreate(savedInstanceState); 
     etInputText.addTextChangedListener(this); 
    } 

    /* 
     This method is called to notify you that, within s, the count characters beginning at 
     start have just replaced old text that had length before. It is an error to attempt to 
     make changes to s from this callback. 
    */ 
    @Override 
    public void onTextChanged(CharSequence s, int start, int before, int count) { 
    } 

    /* 
     This method is called to notify you that, within s, the count characters beginning at start 
     are about to be replaced by new text with length after. 
     It is an error to attempt to make changes to s from this callback. 
    */ 
    @Override 
    public void beforeTextChanged(CharSequence s, int start, int count, int after) { 
     // if count > after then its a char delete cause the no. of chars in 's' 
     // will decrease when the text change is complete. 
     // If count < after 
     // then its a char addition cause the no. of chars in 's' 
     // will increase when the text change is complete. 
     if (count > after) { 
      // CHARACTER DELETION 
      // As 'count' is no. of chars being replaced from 'start' by 
      // 'after' no. of chars, (start+count)-1 will be the index of the 
      // char that that will be deleted. 
      deleteCharIndex = (start + count) - 1; 
      deleteChar = s.charAt(deleteCharIndex); 
      wasCharDeleted = true; 
     } else if (count < after) { 
      // CHARACTER ADDITION 
      // As 'count' is no. of chars being replaced from 'start' by 
      // 'after' no. of chars, (start+after)-1 will will be the index of the 
      // char that will be added. 
      wasCharDeleted = false; 
      addCharIndex = (start + after) - 1; 
     } else { 
      // Extra call to the text changed method with no change in 's'. 
      // Android framework bug?? 
      wasCharDeleted = false; 
      Log.d(TAG, "------EXTRA CALL TO BEFORETEXTCHANGED------"); 
     } 
    } 

    @Override 
    public void afterTextChanged(Editable s) { 
     // Don't process if redundant call to afterTextChanged method. 
     // A framework bug?? 
     if (!prevCharSeq.equals(s.toString())) { 
      if (wasCharDeleted) { 
       // handle char delete 

       if (deleteChar == 'x' 
         && (s.length() == 0 || s.charAt(deleteCharIndex - 1) == ' ')) { 
        // Business logic to deal with the case where the deleted char was an independent 'x' 
       } else { 
        // Business logic to deal with the case where deleted char was anything other than an independent 'x'. 
       } 
      } else { 
       // handle char addition 

       ***if (s.charAt(addCharIndex) == 'x'// CRASH OCCURS ON THIS LINE <-----------------*** 
         && (s.length() == 1 || s.charAt(addCharIndex - 1) == ' ')) { 
        // Business logic to deal with the case where added char is an independent 'x' 
       } else { 
        // Business logic to deal with the case where added char is anything other than an independent 'x' 
       } 
      } 
     } 
     prevCharSeq = s.toString(); 
    } 
} 

3個崩潰至今一直是代碼:

java.lang.IndexOutOfBoundsException: charAt: 24 >= length 23 

java.lang.IndexOutOfBoundsException: charAt: 202 >= length 198 

java.lang.IndexOutOfBoundsException: charAt: 1 >= length 1 

在異常的指標來看,我假設addCharIndex是沒有得到正確計算。這意味着要麼我對beforeTextChanged的參數的理解不正確或者沒有按預期次序調用方法,要麼使用更新的參數多次調用它們,這會更改我的邏輯來計算beforeTextChanged中的addCharIndex

任何有關如何解決此問題的幫助和見解將不勝感激。

謝謝。

+0

爲什麼這個問題downvoted檢查s.length() > 1這種方式?如果我被告知這個問題有什麼問題,我會很感激,這樣我就可以對問題做出適當的修改。 – rbing

回答

1

這不是設備問題。這是一個邏輯問題。

您的問題確實發生在該行之前。因爲當你刪除字符時,你不會更新你的addCharIndex。如果以前的指數爲10,你刪除8個字符,你的指數仍爲10,但只有當您在xd鍵入您的輸入,然後刪除x,你會得到一個崩潰的有2

長度的indexOutOfBoundsException結果那是因爲你的if語句執行以下操作:

s.charAt(deleteCharIndex - 1) == ' '

但因爲你已經刪除了x字符長度您現在是1,但你檢查0或上面的語句是如何得到你的錯誤。如果你不知道if語句中是否有OR(||),它會檢查每個條件,直到它達到真實結果。

有很多方法來解決這個問題,一個辦法就是當你做deleteCharIndex - 1可以打到最低點爲0

+0

感謝您的回答。我看到您指出的錯誤,我會提出修改建議進行修復。但是,崩潰報告中的堆棧跟蹤指向「s.charAt(addedCharacterIndex)=='@'」行。這一行的崩潰是你剛剛指出的錯誤的副產品嗎? – rbing