1

In order to show a chart I have an asyncTask that read a large list of products, get their types and add them to different sublists. This is my code:

   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() {
    }
}

This is the crash:

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)

Line 524 is the productsByTypeSublist.add line. Some crashes are with "length=10; index=10", some are with "length=33; index=33", etc... I guess it depends on what allProducts have (?).

What I don't understand is Why am I getting ArrayIndexOutOfBoundsException in a List.add method?? specially when I have no limit to that arrayList and I'm adding the item without and index, just ant the end of the list?

I've thought maybe it's a thread problem, even if it's a problem with Crashlytics logs and the problem is really in other point of my code.

The code seems pretty simple to me, what am I missing?

Wonton
  • 1,033
  • 16
  • 33

1 Answers1

2

ArrayList is unsynchronized i.e. while one thread is trying to get something from it, another one can modify it and vice versa.

Did you try using productsByType.add(Collections.synchronizedList(new ArrayList<Bundle>()))?

On a side note, you can rewrite the following block

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

simply as

productsByTypeSublist = productsByType.get(Integer.parseInt(productType) - 1);
Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110