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