TextWatcher避免出现StackOverflowError错误

1.TextWatcher

使用TextWatcher可以实现对EditText输入的监听,调用EditText的addTextChangedListener(TextWatcher watcher)方法即可。
TextWatcher是一个接口类,所以必须实现TextWatcher里的3个方法:

public interface TextWatcher extends NoCopySpan {
    public void beforeTextChanged(CharSequence s, int start, int count, int after);
    public void onTextChanged(CharSequence s, int start, int before, int count);
    public void afterTextChanged(Editable s);
}

2.监听器里的setText函数导致StackOverflowError错误

private TextWatcher mTextWatcher = new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            if (null == s || s.length() == 0) {
                return;
            }
            String inputString = s.toString();
            String finalString = getFormatedInputString(inputString);
            if (!TextUtils.isEmpty(finalString)) {
                mEditText.setText(finalString);
                mEditText.setSelection(finalString.length());
            }
        }

        @Override
        public void afterTextChanged(Editable s) {

        }
    };

假如按照上面所写的,一定会产生bug:Java.lang.StackOverflowError
原因分析:在onTextChanged方法中,使用setText()方法,会重新触发监听器,并不断的进行递归,最后导致程序崩溃。

3.解决方法

(1)不要在监听器里写触发监听器的方法,特别是没有出口的方法相互调用。
(2)可以写一个标志位:flag,假如EditText内容发生变化,才执行setText()方法,如果没有发生变化,就不执行监听器里的setText()方法

private TextWatcher mTextWatcher = new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            if (null == s || s.length() == 0) {
                return;
            }
            //setText()会回调onTextChanged(),增加标志位防止出现堆栈溢出
            if (isChange) {
                isChange = false;
                return;
            }
            isChange = true;
            String inputString = s.toString();
            String finalString = getFormatedInputString(inputString);
            if (!TextUtils.isEmpty(finalString)) {
                mEditText.setText(finalString);
                mEditText.setSelection(finalString.length());
            }
        }

        @Override
        public void afterTextChanged(Editable s) {

        }
    };

你可能感兴趣的:(TextWatcher避免出现StackOverflowError错误)