为什么在尝试获取jsonArray项时会出现java.lang.IndexOutOfBoundsException?

时间:2019-05-30 05:09:21

标签: android arrays kotlin recycler-adapter

在我的应用中,我有点像在邮件中附加文件。这些附加文件显示在带有适配器的RecyclerView中。 RV的每个项目都有其自己的btn可以将其删除。问题是当我在列表中有两个项目并尝试删除1个项目而不是第二个项目时,我收到了错误消息。但是,当我尝试删除第二项,然后删除第一项时,一切正常。我使用调试器并设法找到有问题的行,但我不知道如何解决此问题。因此,这是适配器中用于从列表中删除项目的代码:

val array = Singleton.array
if (array!!.size() > 0) {
  for (i in 0 until array.size()) {
   val obj = array.get(i).asJsonObject

   if (obj.get("filename").toString().substring(1, obj.get("filename").toString().length - 1) == mNames[position]) {
   array.remove(obj)
   mNames.removeAt(position)
   Singleton.array = array
   updateNames(mNames)
   }

 }
}

我在此行遇到问题:

val obj = array.get(i).asJsonObject

我通过记录器检查了此变量,一切似乎都正常,我可以用0索引获得值。然后我认为问题出在我向适配器发送数据的地方,但是一切正常。我使用了调试器,并看到方法getAsJsonObject()抛出此异常:

enter image description here

为什么会发生以及如何解决此错误。我试图改变这一点: for (i in 0 until array.size())与此for (i in 0 until array.size()-1)并没有起作用。然后,我尝试将此循环更改为此for (i in 1 until array.size()),但它也无济于事。那么,我在哪里犯了错误,以及将来如何预防该问题?

P.S。很抱歉附加调试器的屏幕截图,因为我无法从中获取文本数据。

4 个答案:

答案 0 :(得分:4)

您已从源数组中删除了元素,这就是为什么会出现异常,因此请使用新数组作为过滤后的值

下面一行的问题

array.remove(obj)

解决方案:

val positionsForRemove = ArrayList<Int>(),
val array = Singleton.array
if (array!!.size() > 0) {
   for (i in 0 until array.size()) {
     val obj = array.get(i).asJsonObject
     if (obj.get("filename").toString().substring(1, obj.get("filename").toString().length - 1) == mNames[position]) 
       positionsForRemove.add(position)
    }
   for(position in positionsForRemove){
          array.remove(position)
          mNames.remove(position)   
        }
  Singleton.array = array
  updateNames(mNames)


}

答案 1 :(得分:3)

您正在for循环迭代中使用remove方法,该方法可以动态更改数组大小。

如果您只需要删除一项,请参阅@Jeeva的答案。

如果要一次从列表中删除多个职位,则必须参考以下方法从数组中删除项目。

val removePositions = ArrayList<Int>(),
val array = Singleton.array
if (array!!.size() > 0) {
  for (i in 0 until array.size()) {
   val obj = array.get(i).asJsonObject

   if (obj.get("filename").toString().substring(1, obj.get("filename").toString().length - 1) == mNames[position])
   //array.remove(obj)
   //mNames.removeAt(position)
   removePositions.add(position)
   //Singleton.array = array
   //updateNames(mNames)
  }

  for (i in 0 until removePositions.size()) {
    array.remove(removePositions[i])
    mNames.remove(removePositions[i])
  }
  Singleton.array = array
  updateNames(mNames)
}

答案 2 :(得分:1)

只需在if条件内添加break语句。

val array = Singleton.array
if (array!!.size() > 0) {
  for (i in 0 until array.size()) {
   val obj = array.get(i).asJsonObject

   if (obj.get("filename").toString().substring(1, obj.get("filename").toString().length - 1) == mNames[position]) {
   array.remove(obj)
   mNames.removeAt(position)
   Singleton.array = array
   updateNames(mNames)
   break;
   }

 }
}

删除第一个元素后获得异常的原因是删除第一个元素后将执行循环。
但是如果您中断了,则下次不会执行。
没有获得异常的原因当您尝试删除第二个元素时,循环恰好在删除第二个元素之后结束。

答案 3 :(得分:0)

亲爱的朋友们,我似乎可以解决此问题,但不确定,因此需要您的检查。因此,我在条件下添加了return语句:

if (obj.get("filename").toString().substring(1, obj.get("filename").toString().length - 1) == mNames[position]) {
array.remove(obj)
mNames.removeAt(position)
Singleton.array = array
updateNames(mNames)
return@setButton
}

因此,当我满足此条件时,我将从删除过程中返回。我想我知道我的应用有时会崩溃的原因-我在警报对话框中按了yes btn,我的对象已从数组中删除,但我的循环继续工作并检查。但是也许我又错了:)