【问题标题】:strange ArrayIndexOutOfBoundsException奇怪的 ArrayIndexOutOfBoundsException
【发布时间】:2012-07-14 04:59:39
【问题描述】:

我遇到了一个非常奇怪的异常。它在这里运行良好,但我的客户一直遇到此异常然后崩溃,我花了很多时间才弄清楚,但不幸的是到目前为止仍然没有运气,任何帮助将不胜感激!

这是代码:

protected void onPostExecute(List<File> result) {
    try {
        mBooks.clear();
        if (result != null) {
            ArrayList<BookInfo> newBooks = new ArrayList<BookInfo>();
            for (File f : result) {
                BookInfo bi = new BookInfo(BookCollections.this, f);
                if (!contains(bi)) {
                    newBooks.add(bi);
                }
            }
            mDB.insertBooks(newBooks);
            mBooks.addAll(newBooks);
            new AlertDialog.Builder(BookCollections.this)
                    .setTitle(newBooks.size() + " Books found!")
                    .setPositiveButton(android.R.string.ok, null)
                    .setView(
            new BookInfoList(BookCollections.this,
            newBooks)).show();
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        mScanDlg.dismiss();
        notifyDataSetChanged();
    }
}

private boolean contains(BookInfo bi) {
    if (bi == null) {
        return true;
    }
    for (BookInfo book : mBooks) {
        if (book.equalTo(bi)) {
            return true;
        }
    }
    for (FolderInfo fi : mFolders) {
        if (fi.getBooks() != null) {
            for (BookInfo book : fi.getBooks()) {
                if (book.equalTo(bi)) {
                    return true;
                }
            }
        }
    }
    return false;
}

请帮助我。谢谢

这个异常(java.lang.ArrayIndexOutOfBoundsException)在

之间引发
for (File f : result) {
    BookInfo bi = new BookInfo(BookCollections.this, f);
    if (!contains(bi)) {
        newBooks.add(bi);
    }
}

【问题讨论】:

  • 添加大量日志记录或发明一种方法来获取发生这种情况的调用堆栈...
  • 你说它在这里工作得很好。这是什么?您是否重新创建了该问题?如果是这样,您可以发布 calltrace 的 logcat 输出吗?

标签: java android indexoutofboundsexception


【解决方案1】:

我注意到您的方法名称是 onPostExecute。这可能是一种处理网络请求的方法吗?如果是这样,那么当您的客户运行此代码时,它可能在多线程 Web 容器中运行。但是,您的集合ArrayList 不是线程安全的集合。这可能是它在您的开发(单线程)环境中工作但在繁忙的服务器上工作的原因。

考虑使用Collections.synchronizedList() 方法来实例化您的ArrayList。请务必遵循 API 文档中关于在同步块中进行迭代的建议。

【讨论】:

  • 一开始我怀疑是多线程造成的,我检查了我使用mBooks和mFolders的所有地方,它们都在UI线程中。我试过了: protected void onPostExecute(List result) { if (result != null) { List lst = Collections.synchronizedList(result); ArrayList newBooks = new ArrayList(); for (File f : lst) { 它仍然失败。
  • 恐怕我第一次没有仔细阅读你的代码。您指出当您迭代作为输入参数传递的集合时会出现问题。我在评论错误的事情(ArrayList)。似乎 List 集合可能会从您的下方发生变化。 Android运行时是否将其传递给您? (我对 Android 知之甚少,无法知道这一点)。如果您可以重现这一点,请添加一个 try-catch 块来捕获异常并打印消息。看看是什么索引导致了问题会很有趣。
【解决方案2】:

几天前我遇到的同样奇怪的行为,其中模拟器应用程序显示完美数据,但在设备中显示错误与 Arraylist 的概念相同我的建议来自您的 PostExecute 删除此行如果您在此之前没有在 ArrayList mBooks

中添加任何内容
mBooks.clear();  // remove this line 

并构建和清理它适用于您的项目,您在使用不同的 arraylist 时遇到了同样的问题,并以这种方式进行排序

是的,你是对的,你的错误来自于此

 for (File f : result) {
                        BookInfo bi = new BookInfo(BookCollections.this, f);
                        if (!contains(bi)) {
                            newBooks.add(bi);
                        }
                    }

首先在 Log as 中检查您的 arraylist 大小

   Log.d("Size",""+newBooks.size());

如果它大于 0,感觉你的数组还有一件事是

更改您的方法 contains bcz 在返回数据时根据您的 if 条件数据插入 newBooks 数组中 contains 方法是 false 我认为你总是得到布尔值 true 所以检查

登录为

Log.d("BooleanValue",""+newBooks.size());

在此 if (!contains(bi)) 条件之前,您可以从日志输出中看到数据已插入 Arraylist 或未根据条件满足

【讨论】:

  • 嗨汗,发生异常时,没有这样的行:mBooks.clear();,我在后面添加了这个用于调试。对此感到抱歉。那条线重要吗? mBooks 数组列表在此之前已经有一些东西,这就是为什么我用 if (!contains(bi)) { 检查是否有重复项
【解决方案3】:

最终发现这是一个普通的ArrayIndexOutOfBoundsException,生成于

BookInfo bi = new BookInfo(BookCollections.this, f);

因为还有一个 for 子句的索引超出了边界。

【讨论】:

    【解决方案4】:
    1. 因为你有“mBooks.clear();”在 onPoseExecute() 的第一行,语句

      for (BookInfo book : mBooks) {  
          if (book.equalTo(bi)) {  
              return true;  
          }  
      }
      

      contains() 中似乎没有任何意义。

    2. 你确定与“FoldInfo fi”相关的书籍不会在外面改变吗?

      for (FolderInfo fi : mFolders) {  
              if (fi.getBooks() != null) {  
                  for (BookInfo book : fi.getBooks()) {  
                      if (book.equalTo(bi)) {  
                          return true;  
                      }  
                  }  
              }  
          }
      

      我认为下面的代码可能会更好:

      for (FolderInfo fi : mFolders) {  
          ArrayList<BookInfo> books = fi.getBooks();  
          if (books  != null) {  
              for (BookInfo book : books) {  
                  if (book.equalTo(bi)) {  
                      return true;  
                  }  
              }  
          }  
      }  
      
    3. 1234563

    【讨论】:

      猜你喜欢
      • 2013-08-25
      • 1970-01-01
      • 2012-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-09
      相关资源
      最近更新 更多