首页 > 解决方案 > IndexOutOfBounds 异常将项目添加到 ArrayList

问题描述

为了显示图表,我有一个 asyncTask 读取大量产品列表,获取它们的类型并将它们添加到不同的子列表中。这是我的代码:

   List<List<Bundle>> productsByType;

   ...

   private class LoadDataForChart extends AsyncTask<Void, Float, Boolean> {

    @Override
    protected void onPreExecute() {
    }

    @Override
    protected Boolean doInBackground(Void... params) {

        productsByType = new ArrayList<>();
        productsByType.add(new ArrayList<Bundle>()); 
        productsByType.add(new ArrayList<Bundle>()); 
        productsByType.add(new ArrayList<Bundle>()); 
        productsByType.add(new ArrayList<Bundle>()); 
        productsByType.add(new ArrayList<Bundle>()); 

        List<Bundle> allProducts = dataManager.getAllProducts();

        for(int i = 0; i < allProducts.size(); i++)
        {
            Bundle product = allProducts.get(i);
            List<Bundle> productsByTypeSublist = null;
            String productType = product.getString("type");
            if(productType.equals("1"))
                productsByTypeSublist = productsByType.get(0);
            else if(productType.equals("2"))
                productsByTypeSublist = productsByType.get(1);
            else if(productType.equals("3"))
                productsByTypeSublist = productsByType.get(2);
            else if(productType.equals("4"))
                productsByTypeSublist = productsByType.get(3);
            else if(productType.equals("5"))
                productsByTypeSublist = productsByType.get(4);

            if(productsByTypeSublist != null)
                productsByTypeSublist.add(product);
        }

        return true;
    }

    @Override
    protected void onProgressUpdate(Float... values) {
    }

    @Override
    protected void onPostExecute(Boolean result) {

        showChartData();
    }

    @Override
    protected void onCancelled() {
    }
}

这是崩溃:

Caused by java.lang.ArrayIndexOutOfBoundsException: length=10; index=10
       at java.util.ArrayList.add(ArrayList.java:468)
       at com.mycompany.myapp.ui.fragments.ChartsFragment$LoadDataForChart.doInBackground(ChartsFragment.java:524)
       at com.mycompany.myapp.ui.fragments.ChartsFragment$LoadDataForChart.doInBackground(ChartsFragment.java:415)
       at android.os.AsyncTask$3.call(AsyncTask.java:378)

第 524 行是 productsByTypeSublist.add 行。有些崩溃是“length=10; index=10”,有些是“length=33; index=33”等等......我想这取决于allProducts有什么(?)。

我不明白的是为什么我在 List.add 方法中得到 ArrayIndexOutOfBoundsException ?特别是当我对该arrayList没有限制并且我添加没有索引的项目时,只是在列表的末尾?

我认为这可能是一个线程问题,即使它是 Crashlytics 日志的问题,而且问题确实出在我代码的其他点。

代码对我来说似乎很简单,我错过了什么?

标签: javaandroidindexoutofboundsexception

解决方案


ArrayList是不同步的,即当一个线程试图从中获取某些东西时,另一个线程可以修改它,反之亦然。

你试过用productsByType.add(Collections.synchronizedList(new ArrayList<Bundle>()))吗?

在旁注中,您可以重写以下块

if(productType.equals("1"))
    productsByTypeSublist = productsByType.get(0);
else if(productType.equals("2"))
    productsByTypeSublist = productsByType.get(1);
else if(productType.equals("3"))
    productsByTypeSublist = productsByType.get(2);
else if(productType.equals("4"))
    productsByTypeSublist = productsByType.get(3);
else if(productType.equals("5"))
    productsByTypeSublist = productsByType.get(4);

就像

productsByTypeSublist = productsByType.get(Integer.parseInt(productType) - 1);

推荐阅读