James King
James King

Reputation: 2445

Android - Invalid index 1, size is 1 - out of bounds

So I have joined a team who are currently writing an android so there is one issue which causes the app to crash. this is due to an arraylist going out of bounds. The code is below and fails is the very last bit of the code (the class goes on and on after this.). I was hoping someone could point out the exact issue and its resolution which doesnt break anything else:

public class OneClickEssentialExtrasFragment extends BaseOneClickFragment {

    public static final String TAG = "PhoneOneClickEssentialExtrasFragment";

    private View myView;

    Map<Integer, Integer> stockProductMap;

    Product mProducts;

    private List<Stock> mStockCollection;

    private List<Stock> mStockDelivery;

    private List<Integer> mStockProductId;

    ArrayList<String> myEssenatialList;

    Map<String, Product> myProduct;

    private String deliveryZipCode = "EC3M3BD";

    WebServiceFacade mWebManager;

    private int ESSENTIAL_EXTRA_PRODUCT_ONE = 0;

    private int ESSENTIAL_EXTRA_PRODUCT_TWO = 1;

    private int ESSENTIAL_EXTRA_PRODUCT_THREE = 2;

    private int currentState = 0;

    private static final int STATE_LOADING = 0;

    private static final int STATE_DISPLAY_ESSENTIAL_EXTRAS = 1;

    public static  String mreservedProduct="";


    public View onCreateView(final LayoutInflater inflater,
            final ViewGroup container, final Bundle savedInstanceState) {
        return inflater.inflate(
                R.layout.fragment_one_click_essential_extras_list, container,
                false);
    }

    public void onViewCreated(final View view, final Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        myView = view;
        currentState = STATE_LOADING;
        Bundle b = getActivity().getIntent().getExtras();
        Product mProduct = b.getParcelable("product");
        mreservedProduct =mProduct.getReference();
        mWebManager = WebServiceFacade.getInstance();
        myProduct = new HashMap<String, Product>();
        Bundle bundle = getActivity().getIntent().getExtras();
        mProducts = bundle.getParcelable("product");

        mStockCollection = new ArrayList<Stock>();
        mStockDelivery = new ArrayList<Stock>();
        mStockProductId = new ArrayList<Integer>();
        mStockProductId.add(Integer.parseInt(mProduct.getReference()));
        // To-do
        myEssenatialList = new ArrayList<String>();
        myEssenatialList.add(mProduct.getReference());
        renderEssentialScreen();
        if (myEssenatialList == null || myEssenatialList.size() == 0) {
            // myView.findViewById(R.id.essential_extras_item_icon_container)
            // .setVisibility(View.GONE);
            resetEssentialViews();
            return;
        }

        if (mProducts != null) {
            for (int i = 0; i < myEssenatialList.size(); i++) {
                mWebManager.getProduct(mProductDetailsCallback,
                        myEssenatialList.get(i));
            }
        } else {

        }
    }

    private void checkStockCollection(Product mProduct, int quantitiesselected) {

        int storeId = 0;
        if(mArgosApplication.getCurrentStore()!=null)
            storeId = mArgosApplication.getCurrentStore().getStoreNumber();

        List<String> products = new ArrayList<String>();
        //TO DO: Get the products list from Order API and add here
        products.add(mProduct.getReference());
        mWebManager.checkStock(mStockCheckCallbackCollection,quantitiesselected, storeId, products,
                deliveryZipCode);
    }

    private final UICallback<Map<Integer, Map<Integer, Stock>>> mStockCheckCallbackCollection = new BaseUICallback<Map<Integer, Map<Integer, Stock>>>() {

        @Override
        protected void handlePlannedMaintenance(final int errorCode,
                final String errorMessage) {
            QLog.d("ignored stock lookup 503 error: " + errorMessage);
        }


        @Override
        public void onSuccess(final Map<Integer, Map<Integer, Stock>> data) {
            if (data != null && mProducts != null) {
                Map<Integer, Stock> productStockMap = null;
                if(mArgosApplication.getCurrentStore()!=null)
                    productStockMap = data.get(mArgosApplication.getCurrentStore().getStoreNumber());
                else // Global stock, see NewStockHandler.java ->convertStockToMap is constructing the map with 1000, in case store URI is null
                    productStockMap = data.get(1000);
                if (productStockMap != null) {
                    for (int index = 0; index < productStockMap.size(); index++) {
                        if (mStockProductId != null) {
                            mStockCollection.add(productStockMap
                                    .get(mStockProductId.get(index)));
                            currentState = STATE_DISPLAY_ESSENTIAL_EXTRAS;
                            renderEssentialScreen();
                        }
                    }
                }
            } else {
                QLog.d("No Response for Product");
            }
        }


        @Override
        public boolean handleFailure(int errorCode, String errorMessage) {
            QLog.d("503 Stock Check not Available");
            return false;
        }
    };

    private void renderEssentialScreen() {
        if (myEssenatialList == null || myEssenatialList.size() == 0) {
            resetEssentialViews();
        }
        switch (currentState) {
        case STATE_LOADING:
            renderProgressBar();
            break;
        case STATE_DISPLAY_ESSENTIAL_EXTRAS:
            renderEssentialData();
            break;
        }
    }

    private void renderProgressBar() {
        resetEssentialViews();
        myView.findViewById(R.id.progressbar).setVisibility(View.VISIBLE);
    }

    private void renderEssentialData() {
        myView.findViewById(R.id.progressbar).setVisibility(View.GONE);
        if (myEssenatialList == null || myEssenatialList.size() == 0) {
            resetEssentialViews();
            return;
        }
        resetEssentialViews();
        if (myEssenatialList.size() == ESSENTIAL_EXTRA_PRODUCT_ONE) {
            fillProductFirst();
        } else if (myEssenatialList.size() == ESSENTIAL_EXTRA_PRODUCT_TWO) {
            fillProductFirst();
            fillProductMiddle();
        } else {
            fillProductFirst();
            fillProductMiddle();
            fillProductLast();
        }
    }

    private void resetEssentialViews() {
        myView.findViewById(R.id.essential_extras_one).setVisibility(View.GONE);
        myView.findViewById(R.id.essential_extras_two).setVisibility(View.GONE);
        myView.findViewById(R.id.essential_extras_three).setVisibility(
                View.GONE);
    }

    private void fillProductMiddle() {

        if (isAdded() == false) {
            return;
        }


        System.out.println("size of array = " + myEssenatialList.size());
        for(int i =0; i <myEssenatialList.size(); i++){
            System.out.println("elements of array are: " + i);
        }

        myView.findViewById(R.id.essential_extras_two).setVisibility(View.VISIBLE);
        TextView productDescription = (TextView)myView.findViewById(R.id.product_name_two);
        productDescription.setText(myProduct.get(myEssenatialList.get(ESSENTIAL_EXTRA_PRODUCT_TWO))
                .getShortDescription());

Thanks.

UPDATE:

blow is the logout output:

10-16 08:19:11.280: E/AndroidRuntime(23119): FATAL EXCEPTION: main
10-16 08:19:11.280: E/AndroidRuntime(23119): java.lang.IndexOutOfBoundsException: Invalid index 1, size is 1
10-16 08:19:11.280: E/AndroidRuntime(23119):    at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
10-16 08:19:11.280: E/AndroidRuntime(23119):    at java.util.ArrayList.get(ArrayList.java:308)
10-16 08:19:11.280: E/AndroidRuntime(23119):    at android.fragment.pdp.OneClickEssentialExtrasFragment.fillProductMiddle(OneClickEssentialExtrasFragment.java:352)
10-16 08:19:11.280: E/AndroidRuntime(23119):    at android.fragment.pdp.OneClickEssentialExtrasFragment.renderEssentialData(OneClickEssentialExtrasFragment.java:312)
10-16 08:19:11.280: E/AndroidRuntime(23119):    at android.fragment.pdp.OneClickEssentialExtrasFragment.renderEssentialScreen(OneClickEssentialExtrasFragment.java:287)
10-16 08:19:11.280: E/AndroidRuntime(23119):    at android.fragment.pdp.OneClickEssentialExtrasFragment.access$4(OneClickEssentialExtrasFragment.java:278)
10-16 08:19:11.280: E/AndroidRuntime(23119):    at android.fragment.pdp.OneClickEssentialExtrasFragment$1.onSuccess(OneClickEssentialExtrasFragment.java:252)
10-16 08:19:11.280: E/AndroidRuntime(23119):    at android.fragment.pdp.OneClickEssentialExtrasFragment$1.onSuccess(OneClickEssentialExtrasFragment.java:1)
10-16 08:19:11.280: E/AndroidRuntime(23119):    at android.webservices.WebServiceExecutor$WebMethodTask.onPostExecute(WebServiceExecutor.java:466)
10-16 08:19:11.280: E/AndroidRuntime(23119):    at android.webservices.WebServiceExecutor$WebMethodTask.onPostExecute(WebServiceExecutor.java:1)
10-16 08:19:11.280: E/AndroidRuntime(23119):    at android.os.AsyncTask.finish(AsyncTask.java:631)
10-16 08:19:11.280: E/AndroidRuntime(23119):    at android.os.AsyncTask.access$600(AsyncTask.java:177)
10-16 08:19:11.280: E/AndroidRuntime(23119):    at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
10-16 08:19:11.280: E/AndroidRuntime(23119):    at android.os.Handler.dispatchMessage(Handler.java:99)
10-16 08:19:11.280: E/AndroidRuntime(23119):    at android.os.Looper.loop(Looper.java:137)
10-16 08:19:11.280: E/AndroidRuntime(23119):    at android.app.ActivityThread.main(ActivityThread.java:5103)
10-16 08:19:11.280: E/AndroidRuntime(23119):    at java.lang.reflect.Method.invokeNative(Native Method)
10-16 08:19:11.280: E/AndroidRuntime(23119):    at java.lang.reflect.Method.invoke(Method.java:525)
10-16 08:19:11.280: E/AndroidRuntime(23119):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
10-16 08:19:11.280: E/AndroidRuntime(23119):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
10-16 08:19:11.280: E/AndroidRuntime(23119):    at dalvik.system.NativeStart.main(Native Method)
10-16 08:19:17.910: E/Google Maps Android API(23119): Failed to load map. Error contacting Google servers. This is probably an authentication issue (but could be due to network errors).

Upvotes: 0

Views: 5006

Answers (2)

Shubhank
Shubhank

Reputation: 21805

According to your crash stack trace.

at java.util.ArrayList.get(ArrayList.java:308) 10-16 08:19:11.280: E/AndroidRuntime(23119):

android.fragment.pdp.OneClickEssentialExtrasFragment.fillProductMiddle(OneClickEssentialExtrasFragment.java:352)

which i believe is this line

productDescription.setText(myProduct.get(myEssenatialList.get(ESSENTIAL_EXTRA_PRODUCT_TWO))
                .getShortDescription());

you should debug this line and split it into individual array accessing.. since you are chaining two get inside single statement so debugging which array is being accessed out of bounds is difficult. after splitting you can debug which is being accessed out of bounds and why.

Upvotes: 0

sandymatt
sandymatt

Reputation: 5612

This is a simple off-by-one mistake.

You're doing this:

myProduct.get(myEssenatialList.get(ESSENTIAL_EXTRA_PRODUCT_TWO))

where:

private int ESSENTIAL_EXTRA_PRODUCT_TWO = 1;

What if your list only has 1 element? you want the 0th item in that case. Trying to access the 1st element will throw an out of bounds exception.

Upvotes: 1

Related Questions