使用EditText出现java.lang.StackOverflowError报错

最近项目中有个在EditText中输入子网掩码(xxx.xxx.xxx.xxx)形式的需求,只需
手动填入数字,自动添加”.”进去。于是想到了EditText的addTextChangedListener,
不过在editText.setText()时就碰到了问题,报了java.lang.StackOverflowError错误。

 @Override
 public void onTextChanged(CharSequence s, int start, int before, int count) {
     StringBuilder sb = new StringBuilder();//111.222.333.444
     if (s == null || s.length() == 0) return;
     for (int i = 0; i < s.length(); i++) {
         if (i != 3 && i != 7 && i != 11 && s.charAt(i) == '.') {
               continue;
          } else {
              sb.append(s.charAt(i));
         if ((sb.length() == 4 || sb.length() == 8 || sb.length() == 12) && sb.charAt(sb.length() - 1) != '.') {
              sb.insert(sb.length() - 1, ".");
              }
           }
        }
        editText.setText(sb.toString()); // 此处原因报错
   }

由于每次EditText有变动就会触发onTextChanged(),就会一直递归 执行editText.setText();
造成当前线程栈满了,就会使程序崩溃。

我们只要增加条件去中断这种递归即可解决问题,不满足条件就不执行。

@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
     StringBuilder sb = new StringBuilder();//111.222.333.444
     if (s == null || s.length() == 0) return;
     for (int i = 0; i < s.length(); i++) {
         if (i != 3 && i != 7 && i != 11 && s.charAt(i) == '.') {
               continue;
          } else {
              sb.append(s.charAt(i));
         if ((sb.length() == 4 || sb.length() == 8 || sb.length() == 12) && sb.charAt(sb.length() - 1) != '.') {
              sb.insert(sb.length() - 1, ".");
              }
           }
        }
        if (!sb.toString().equals(s.toString())) { //增加条件
            editText.setText(sb.toString());
            Log.d("Position", start + "/" + before + "/" + count + "/" + sb.toString() + "/" + s.toString());
        }
   }

当输入1234时,Log日志为

D/Position: 0/3/4/123.4/1234

sb.toString()的值是123.4,而s.toString()的值是1234,两个值不同才会执行setText()方法。

总之,我们只需要提供一个递归出口就能解决问题。

### 回答1: 此错误是由于尝试在空对象引用上调用虚拟方法 'void android.widget.EditText.setText(java.lang.CharSequence)' 引起的。可以检查代码调用setText的对象是否实例化或已初始化。 ### 回答2: 这个错误提示表明在Java代码,有一个对象引用为空,即null,而后面的函数调用却试图访问该对象的一个方法,导致了崩溃。 在这个错误信息,我们可以看到是在尝试调用一个EditText组件的setText函数时出现错误。也就是说,该对象是一个EditText组件,而该组件的setText函数被调用时,程序发现该组件本身并没有被正确地初始化或者已经被释放掉,因此引发了该错误。 这个问题通常发生在以下几种情况下: 1. 在使用findViewById函数时,没有指定正确的ID,导致找不到对应的组件,进而返回null。 2. 在使用Fragment或者Activity的生命周期函数时,例如onCreate()、onResume()或onStart()等等,在这些函数如果直接调用一个尚未被创建的组件实例时,就会返回null导致出现这个异常。 3. 在Fragment或者Activity调用另一个组件时,由于一些其他的问题没有成功获取到正确的组件实例,导致该组件实例为空。 为了避免这个问题,可以使用一些技术避免空指针异常的发生,例如使用非空注解(@NonNull)、使用try-catch代码块来捕捉异常、对每个EditText组件实例设置默认值或默认文本等。 ### 回答3: 在 Android 开发过程,经常会遇到 "Attempt to invoke virtual method 'void android.widget.EditText.setText(java.lang.CharSequence)' on a null object reference" 的错误。这个错误通常意味着你的代码尝试在一个空对象上调用实例方法。在本文,我将解释这个错误的原因和解决方法。 错误原因 当我们在代码创建 EditText 控件时,我们需要为其分配一个唯一的ID,然后我们可以使用 findViewById() 方法来获取该控件。如果我们忘记为 EditText 控件分配 ID 或者分配错误的 ID,那么在使用 findViewById() 方法时就会返回 null,这就是出现错误的原因。 解决方法 解决这个错误的方法很简单。只需要检查代码EditText 控件是否正确地分配了 ID。如果没有为 EditText 分配 ID,可以在 XML 文件手动添加一个 ID,如下所示: <EditText android:id="@+id/editText" android:layout_width="match_parent" android:layout_height="wrap_content"/> 在代码,可以使用 findViewById() 方法获取 EditText 控件的 ID。如果该控件没有被正确分配 ID,findViewById() 方法将会返回 null,因此在使用 setText() 方法之前必须检查控件是否为空。 下面是一个简单的示例代码片段,演示了如何检查并设置 EditText 控件的文本: EditText editText = findViewById(R.id.editText); if (editText != null) { editText.setText("Hello World!"); } 总结 这篇文章解释了 "Attempt to invoke virtual method 'void android.widget.EditText.setText(java.lang.CharSequence)' on a null object reference" 错误的原因和解决方法。这个错误通常是因为忘记为 EditText 控件分配 ID 或者分配错误的 ID,导致在使用 findViewById() 方法时返回 null。解决这个问题可以通过在 XML 文件EditText 控件添加正确的 ID,并在在代码使用 findViewById() 方法之前检查控件是否为空。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值