Home > Enterprise >  Crash occurring on some devices and not on others with IndexOutOfBounds exception | Android
Crash occurring on some devices and not on others with IndexOutOfBounds exception | Android

Time:09-25

I have a really huge problems. My app crashes on some devices, and not on others, and I don't know at all why, this is not a problem with Android resources or display or things like that but the exception is caused by Array I use (that's why I don't understand difference between phones). The exception is :

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.jojo.jojozquizz/com.jojo.jojozquizz.SelectCategoriesActivity}: java.lang.ArrayIndexOutOfBoundsException: length=28; index=28
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2913)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6669)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
     Caused by: java.lang.ArrayIndexOutOfBoundsException: length=28; index=28
        at com.jojo.jojozquizz.tools.CategoriesHelper.getProcessedCategories(CategoriesHelper.java:45)
        at com.jojo.jojozquizz.SelectCategoriesActivity.onCreate(SelectCategoriesActivity.java:65)
        at android.app.Activity.performCreate(Activity.java:7136)
        at android.app.Activity.performCreate(Activity.java:7127)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2893)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048) 
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78) 
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808) 
        at android.os.Handler.dispatchMessage(Handler.java:106) 
        at android.os.Looper.loop(Looper.java:193) 
        at android.app.ActivityThread.main(ActivityThread.java:6669) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858

My activity code :

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_select_categories);

        mBinding = DataBindingUtil.setContentView(this, R.layout.activity_select_categories);
        mBinding.setHandler(this);
        mBinding.setSwitchHandler(this);

        mPreferences = this.getSharedPreferences("com.jojo.jojozquizz", MODE_PRIVATE);
        int userId = mPreferences.getInt("currentUserId", 0);
        mPlayer = PlayersDatabase.getInstance(this).PlayersDAO().getPlayer(userId);

        mCategoriesHelper = new CategoriesHelper(this);

        mOldCategoriesSelected = mCategoriesHelper.getProcessedCategories(mPlayer.getCategoriesSelected());
        mNewCategoriesSelected = mOldCategoriesSelected;

        mSelectAllSwitch = mBinding.switchSelectAll;
        mCheckboxEasy = mBinding.activitySelectCategoriesCheckboxFacile;
        mCheckboxMedium = mBinding.activitySelectCategoriesCheckboxMoyen;
        mCheckboxHard = mBinding.activitySelectCategoriesCheckboxDifficile;
        mCheckBoxes = new MaterialCheckBox[]{mCheckboxEasy, mCheckboxMedium, mCheckboxHard};

        mCategoriesAdapter = new CategoriesAdapter(this, mCategoriesHelper.getCategories(), mOldCategoriesSelected);
        mRecyclerView = mBinding.recyclerCategories;
        mRecyclerView.setAdapter(mCategoriesAdapter);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));

        mDifficultiesSelected = mCategoriesHelper.getProcessedDifficulties(mPlayer.getDifficultiesSelected());

        int i = 0;
        for (CheckBox checkBox : mCheckBoxes) {
            checkBox.setText(mCategoriesHelper.getDifficulties()[i]);
            checkBox.setChecked(mDifficultiesSelected.contains(checkBox.getText().toString()));
            i  ;
        }
    }

And my class CategoriesHelper :

package com.jojo.jojozquizz.tools;

import android.content.Context;

import com.jojo.jojozquizz.R;

import java.util.ArrayList;
import java.util.List;

public class CategoriesHelper {

    private Context context;
    private final String[] categories;
    private final String[] difficulties;

    public CategoriesHelper(Context ct) {
        this.context = ct;
        this.categories = ct.getResources().getStringArray(R.array.categories);
        this.difficulties = ct.getResources().getStringArray(R.array.difficulties);
    }

    public String processCategories(List<String> categoriesGiven) {
        StringBuilder valueToReturn = new StringBuilder();

        for (String category : categories) {
            if (categoriesGiven.contains(category))
                valueToReturn.append("1");
            else
                valueToReturn.append("0");
        }

        return valueToReturn.toString();
    }

    public List<String> getProcessedCategories(String processedCategories) {

        String[] array = processedCategories.split("");

        List<String> valuesToReturn = new ArrayList<>();

        int i = 0;

        for (String character : array) {
            if (character.equals("1"))
                valuesToReturn.add(categories[i]);
            i  ;
        }
        return valuesToReturn;
    }

    public String processDifficulties(List<String> difficultiesGiven) {

        StringBuilder valueToReturn = new StringBuilder();

        for (String difficulty : difficulties) {
            if (difficultiesGiven.contains(difficulty))
                valueToReturn.append("1");
            else
                valueToReturn.append("0");
        }

        return valueToReturn.toString();
    }

    public List<String> getProcessedDifficulties(String processedDifficulties) {

        String[] array = processedDifficulties.split("");

        List<String> valuesToReturn = new ArrayList<>();

        int i = 0;

        for (String character : array) {
            if (character.equals("1"))
                valuesToReturn.add(difficulties[i]);
            i  ;
        }

        return valuesToReturn;
    }

    public String getAllCategoriesProcessed() {
        StringBuilder valueToReturn = new StringBuilder();

        for (String ignored : this.categories) {
            valueToReturn.append("1");
        }

        return valueToReturn.toString();
    }

    public String getNoneCategoriesProcessed() {
        StringBuilder valueToReturn = new StringBuilder();

        for (String ignored : this.categories) {
            valueToReturn.append("0");
        }

        return valueToReturn.toString();
    }

    public String getAllDifficultiesProcessed() {
        StringBuilder valueToReturn = new StringBuilder();

        for (String ignored : this.difficulties) {
            valueToReturn.append("1");
        }

        return valueToReturn.toString();
    }

    public String getNoneDifficultiesrocessed() {
        StringBuilder valueToReturn = new StringBuilder();

        for (String ignored : this.difficulties) {
            valueToReturn.append("0");
        }

        return valueToReturn.toString();
    }

    public String[] getCategories() {
        return this.categories;
    }

    public String[] getDifficulties() {
        return this.difficulties;
    }
}

I know this is a weird way to do, but that's how I do, hope you can help me, thanks.

CodePudding user response:

I think An Array length of 1 means that only the index 0 exist because in java array indexes start with 0!

Or in other words, the Boundaries of an Array are Array.length -1

CodePudding user response:

the crash is here in CategoriesHelper class:

    public List<String> getProcessedDifficulties(String processedDifficulties) {
    ...

    int i = 0;
    for (String character : array) {
        if (character.equals("1"))
            valuesToReturn.add(difficulties[i]);
        i  ;
    }
    return valuesToReturn;
   }

in valuesToReturn.add(difficulties[i]); You are passing i index which is in processedDifficulties to difficulties. I don't know how your logic is working and what is the relation between processedDifficulties and difficulties but finding an index in an array and passing it to another array is always in danger of IndexOutOfBoundsException. because there is no guarantee that the sizes of two arrays are always equal and the same.

  • Related