1

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

这是代码:

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

4 回答 4

3

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

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

于 2012-07-14T05:28:50.337 回答
0

最终发现这是一个普通ArrayIndexOutOfBoundsException的,在

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

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

于 2012-07-15T13:39:37.990 回答
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 as 中检查您的 arraylist 大小

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

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

当通过contains方法返回数据为false时,根据您的if条件数据插入newBooks数组,更改您的方法包含 bcz我认为您总是得到布尔值true ,因此对于该检查

在登录为

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

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

于 2012-07-14T05:35:47.613 回答
0
  1. 因为你有“mBooks.clear();” 在 onPoseExecute() 的第一行,语句

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

    incontains()似乎没有任何意义。

  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)在不同的线程中运行时,最好考虑使用一些锁来保护您mBooks的. mFoldersmDB

于 2012-07-16T01:10:00.093 回答