TextWatcher内でこのコードを使用すると、stackoverflow
エラーが発生します。
txt.setText(s.toString().substring(0, s.length()-1) + "a");
なぜこれが発生し、どうすればそれを防ぐことができますか?私はそれを使用しonTextChanged
、afterTextChanged
それらの両方がスタックオーバーフローを生成します
TextWatcher内でこのコードを使用すると、stackoverflow
エラーが発生します。
txt.setText(s.toString().substring(0, s.length()-1) + "a");
なぜこれが発生し、どうすればそれを防ぐことができますか?私はそれを使用しonTextChanged
、afterTextChanged
それらの両方がスタックオーバーフローを生成します
このコードは壊れています。擬似コードでは、
//whenever the text changes, replace the last letter with an 'a'
新しいテキストが古いテキストと一致する場合でも、テキストの設定はテキストの変更であるため、「a」が別の「a」に置き換えられるたびに、スタックがいっぱいになるまで繰り返します。
のようなターミナルケースがあった場合
if (!txt.endsWith("a"))
そうすれば、これはオーバーフローしません。
私が使用した解決策は、再帰の原因となるリスナーを一時的に無効にすることです。
注:RichEditTextはEditTextのサブクラスです。例えば。
@Override
public void afterTextChanged(Editable s)
{
...
RichEditText.this.removeTextChangedListener(this); //disable listener
//Change s here. Changes made to s will not cause recursion since the listener is disabled
RichEditText.this.addTextChangedListener(this); //reenable listener
...
}
もちろん、StackOverFlowエラーが発生します。何かが変更されるたびに、コールバックonTextChanged
が呼び出されます。次に、その中でテキストを再度変更します。
ドキュメントによると:
このメソッドは、s内のどこかでテキストが変更されたことを通知するために呼び出されます。このコールバックからsにさらに変更を加えることは正当ですが、無限ループに入らないように注意してください
無限ループを回避するための条件が必要です。例えば:
if(s.charAt(s.length()-1)!='a')
s = s.append("a");