Android textwatcher上的IndexOutOfBoundsException
我正在使用textwatcher检查用户输入的有效性。我的一些用户因为这个textwacher而崩溃。以下是谷歌提供的stacktrace:Android textwatcher上的IndexOutOfBoundsException,android,textwatcher,Android,Textwatcher,我正在使用textwatcher检查用户输入的有效性。我的一些用户因为这个textwacher而崩溃。以下是谷歌提供的stacktrace: java.lang.IndexOutOfBoundsException: Invalid index 1, size is 1 at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255) at java.util.ArrayList.get(ArrayList.jav
java.lang.IndexOutOfBoundsException: Invalid index 1, size is 1
at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
at java.util.ArrayList.get(ArrayList.java:308)
at android.widget.TextView.sendAfterTextChanged(TextView.java:7997)
at android.widget.TextView$ChangeWatcher.afterTextChanged(TextView.java:10043)
at android.text.SpannableStringBuilder.sendAfterTextChanged(SpannableStringBuilder.java:970)
at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:497)
at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:435)
at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:30)
at android.view.inputmethod.BaseInputConnection.replaceText(BaseInputConnection.java:679)
at android.view.inputmethod.BaseInputConnection.setComposingText(BaseInputConnection.java:437)
at com.android.internal.view.IInputConnectionWrapper.executeMessage(IInputConnectionWrapper.java:333)
at com.android.internal.view.IInputConnectionWrapper$MyHandler.handleMessage(IInputConnectionWrapper.java:77)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5584)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084)
at dalvik.system.NativeStart.main(Native Method)
我的代码是:
Zipcode.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void afterTextChanged(Editable editable) {
if (editable.toString().equals(zc)) return;
zc = editable.toString();
isZipcodeChecked = false;
Log.d(TAG, "Text changed : " + editable.toString());
if (editable.toString().length() != 5) {
Zipcode.setTextColor(Color.RED);
return;
}
checkZipcode(editable.toString());
}
});
关于这是怎么发生的,我没有更多的信息。它在大多数情况下工作正常,我无法复制这个bug。你知道发生了什么吗?答案已经在评论中给出了,但很难看出你是不是像我一样匆匆走过。因此,真正的答案是: 避免添加TextWatcher两次或多次,因为第一次添加将编辑内容,后续添加将导致异常 由于无法检查EditText是否已设置TextWatcher,因此我使用布尔值构建了自己的解决方案,用于检查TextWatcher是否已添加
private EditText mEditText;
private TextWatcher mTextWatcher;
private boolean mTextWatcherIsEnabled = false;
public void setTextWatcher(TextWatcher textWatcher) {
mTextWatcher = textWatcher;
}
public void enableTextWatcher() {
if (!mTextWatcherIsEnabled) {
mEditText.addTextChangedListener(mTextWatcher);
}
mTextWatcherIsEnabled = true;
}
public void disableTextWatcher() {
if (mTextWatcherIsEnabled) {
mEditText.removeTextChangedListener(mTextWatcher);
}
mTextWatcherIsEnabled = false;
}
对我来说,之所以发生这种情况,是因为我在同一个视图中添加了两个不同的
TextWatcher
s,而我首先添加的是删除它本身:
view.addTextChangedListener(new ListenerA());
view.addTextChangedListener(new ListenerB());
因为第一个会删除自身,所以会在此处导致索引越界异常:
private void sendBeforeTextChanged(CharSequence text, int start, int before, int after) {
if (mListeners != null) {
final ArrayList<TextWatcher> list = mListeners;
final int count = list.size();
for (int i = 0; i < count; i++) {
list.get(i).beforeTextChanged(text, start, before, after);
}
}
// ...
}
private void sendBeforeTextChanged(字符序列文本、int-start、int-before、int-after){
如果(mListeners!=null){
最终ArrayList列表=mListeners;
最终整数计数=list.size();
for(int i=0;i
查询计数
,列表大小为2
。因此它调用get(0)
,然后将其自身移除。然后它调用get(1)
,但现在列表大小仅为1
,因此会引发异常
我解决了这个问题,一开始并没有删除我的TextWatcher,而是禁用了这个行为。你也可以通过保证列表中只有最后一个观察者会删除自己来解决这个问题。checkZipcode函数的代码在哪里?@Laetan,你的要求是什么?检查你是否要添加两次侦听器。正如@GabrieleMariotti已经说过的,如果你添加两次或更多侦听器,这种情况通常会发生。第一个将编辑内容,随后的一个将导致异常。刚刚选中。在某些情况下,添加了第二个TextWatcher。可能是问题,嗨!我也遇到了同样的问题,但我的文本观察者不会修改内容——只是对外部的变化做出反应。它还在幕后编辑它的内容吗?@MichałPowłoka没有代码就很难说了。我建议你打开一个带有错误消息和代码的新问题,如果你从这里链接到它,我可以看一看:)我没有删除textwatcher,但仍然得到了异常。此外,为了以防万一,我使用了
addTextChangedListener
扩展名。
private void sendBeforeTextChanged(CharSequence text, int start, int before, int after) {
if (mListeners != null) {
final ArrayList<TextWatcher> list = mListeners;
final int count = list.size();
for (int i = 0; i < count; i++) {
list.get(i).beforeTextChanged(text, start, before, after);
}
}
// ...
}