0

私のアプリでは入力をEditTextで追跡したいと思います。ユーザーは、私が追跡したいEditTextで文字を変更するたび:TextWatcherのIndexOutOfBoundsException

  1. 文字が/追加された場合は、た
  2. インデックス文字が削除/追加された/時と
  3. 何の文字を削除しました追加/削除

私はこれを達成するためにTextWatcherを使用します。私のアプローチは今まではうまくいっています。しかし、最近私の生産アプリでIndexOutOfBoundsExceptionと3つのクラッシュがありました。私が注目したことの一つは、すべてのクラッシュが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のパラメータの私の理解が間違っているか、または TextWatcherメソッドが期待された順序で呼び出されていないか、または beforeTextChangedaddCharIndexを計算するロジックを乱している更新された引数で複数回呼び出されることを意味します。

この問題に対処する方法についての助力と洞察力があれば幸いです。

ありがとうございました。

+0

がなぜこの質問は、downvotedしていることを確認することで、それを修正するには、多くの方法がありますか?私は質問に問題があると言われたらそれを感謝して、質問に適切な変更を加えることができます。 – rbing

答えて

1

これはデバイスの問題ではありません。それは論理的な問題です。

実際に問題が発生するのは、その前の行です。文字を削除すると、addCharIndexは更新されません。以前のインデックスが10で、8文字を削除してもインデックスは10ですが長さは2です。

xdと入力してxを削除すると、

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

しかし、あなたの長さは今1ですが、あなたは0またはどのようにあなたは上記の文をチェックしているx文字を削除したので、:文がない場合、あなたは、次のためだindexOutOfBoundsExceptionの結果あなたのエラーを取得します。 if文にOR(||)があるかどうかわからない場合は、真の結果になるまですべての条件をチェックします。

一つの方法は、あなたが行うときs.length() > 1この方法あなたがヒットすることができdeleteCharIndex - 1最低点は0

+0

答えをありがとう。私があなたが指摘した欠陥を見て、それを修正するための提案された変更を行います。ただし、クラッシュレポートのスタックトレースは "s.charAt(addedCharacterIndex)== '@'"行を指しています。この行のクラッシュは、あなたが指摘したバグの副産物ですか? – rbing

関連する問題