Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/353.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 奇怪的阵列索引边界外感知_Java_Android_Indexoutofboundsexception - Fatal编程技术网

Java 奇怪的阵列索引边界外感知

Java 奇怪的阵列索引边界外感知,java,android,indexoutofboundsexception,Java,Android,Indexoutofboundsexception,我遇到了一个非常奇怪的例外。它在这里运行良好,但我的客户不断遇到此异常,然后崩溃,我花了很多小时才弄清楚,但不幸的是,到目前为止仍然没有运气,任何帮助都将不胜感激 代码如下: protected void onPostExecute(List<File> result) { try { mBooks.clear(); if (result != null) { ArrayList<BookInfo> newB

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

代码如下:

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

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


考虑使用方法实例化ArrayList。请务必遵循API文档中关于在同步块内迭代的建议。

这是我几天前遇到的同样奇怪的行为,emulator应用程序显示perfact数据,但在设备中显示错误,与Arraylist的概念相同。我的建议来自您的PostExecute如果未添加,请删除此行在此之前,ArrayListmBooks中的任何内容

mBooks.clear();  // remove this line 
并且构建和清理你的项目,它为你工作,你在不同的arraylist中遇到同样的问题,并以这种方式进行整理

是的,你是对的,你的错误就在这里

 for (File f : result) {
                        BookInfo bi = new BookInfo(BookCollections.this, f);
                        if (!contains(bi)) {
                            newBooks.add(bi);
                        }
                    }
首先检查日志中的arraylist大小

   Log.d("Size",""+newBooks.size());
Log.d("BooleanValue",""+newBooks.size());
如果大于0,则表示数组中的

根据您的更改方法containsbcz,如果条件数据插入newBooks数组,当contains方法返回的数据为false时,我想您总是会得到布尔值true,因此对于该检查

登录为

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

在此之前如果(!contains(bi))从日志输出中可以看到数据是否插入到Arraylist中,这取决于满足的条件

这最终被发现是在中生成的普通
ArrayIndexOutOfBoundsException

BookInfo bi = new BookInfo(BookCollections.this, f);
因为还有另一个for子句的索引超出了边界

  • 由于在onPoseExecute()的第一行中有“mBooks.clear();”,语句

    for (BookInfo book : mBooks) {  
        if (book.equalTo(bi)) {  
            return true;  
        }  
    }
    
    contains()
    中似乎没有任何意义

  • 您确定与“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;  
                }  
            }  
        }  
    }  
    
    for(FolderInfo-fi:mFolders){
    ArrayList books=fi.getBooks();
    如果(books!=null){
    对于(图书信息图书:图书){
    if(book.equalTo(bi)){
    返回true;
    }  
    }  
    }  
    }  
    
  • 当您使用AsYcCask和一些代码(不是这个PASSCORT)在不同的线程中运行时,最好考虑使用一些锁来保护您的<代码> MBOOKS ,<代码> MFLIDss/COD> >并且可能<代码> MDB。p>


  • 添加大量日志记录,或者发明一种方法来获取发生这种情况时的调用堆栈……您可以说它在这里工作得很好。这是什么?您是否重新创建了该问题?如果是这样的话,你能为calltrace发布logcat输出吗?我起初怀疑这是由多线程引起的,我检查了我使用mBooks和MFolder的所有位置,它们都在UI线程中。我尝试了:protectedvoid onPostExecute(List result){if(result!=null){List lst=Collections.synchronizedList(result);ArrayList newBooks=new arrarylist();for(文件f:lst){它仍然失败。恐怕我第一次没有仔细阅读您的代码。您在迭代作为输入参数传递的集合时指出出现了问题。我的评论是错误的(ArrayList).看起来列表集合可能会从您的下方更改。Android运行时是否会将其传递给您?(我对Android的了解还不够,无法了解这一点)。如果可以重现此情况,请添加一个try-catch块以捕获异常并打印消息。查看导致此问题的索引将非常有趣。嗨,Khan,当异常发生时,没有这样的行:mBooks.clear();之后,我添加了此项以进行调试。很抱歉。这行是否重要?mBooks arraylist在此之前已经有了一些内容,这就是为什么我使用if(!contains(bi))检查是否存在重复项的原因{