奇怪的ArrayIndexOutOfBoundsException

时间:2012-07-14 04:59:40

标签: java android indexoutofboundsexception

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

这是代码:

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);
    }
}

4 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分:0)

我在仿真器应用程序显示完整数据的几天之前遇到的同样奇怪的行为但在设备中它显示错误与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中检查你的arraylist大小

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

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

更改您的方法包含 bcz,当您包含返回数据时如果条件数据插入 newBooks 数组中strong>方法 false 我认为你总是得到布尔值 true 所以对于那个检查

在日志中

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

在此 if(!contains(bi))条件之前,您可以看到根据条件满足

将数据插入到Arraylist中

答案 2 :(得分:0)

最终发现这是在

中生成的普通ArrayIndexOutOfBoundsException
BookInfo bi = new BookInfo(BookCollections.this, f);

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

答案 3 :(得分:0)

  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. 当您使用AsyncTask并且某些代码(不是此postexecute)在不同的线程中运行时,最好考虑使用一些锁来保护您的mBooksmFolders和{ {1}}。