App crashing at the end of array

2020-04-17 05:05发布

问题:

My app is crashing at the end of the array in bluestacks. I have no idea why.

When I click the next button at the end of the array, the app crashes. I also tested it on my phone, same result. The rest of the app functions as intended.

From what I know "i %= image_elements.length;" is supposed to be the function that loops the array.

I am pretty sure this is where the crash is coming from.

i++;

element.setImageResource(image_elements[i]);
name.setImageResource(image_names[i]);

i %= image_elements.length;

Full code below

public class Practice extends MainMenuActivity {

    int i = 0;
    final int[] image_elements = {
        R.drawable.spr_elements_0,
        R.drawable.spr_elements_1,
        [...]
        R.drawable.spr_elements_86,
        R.drawable.spr_elements_87,
    };
    final int[] image_names = {
        R.drawable.spr_name_0,
        R.drawable.spr_name_1,
        [...]
        R.drawable.spr_name_86,
        R.drawable.spr_name_87,
    };

    protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.practice);

            final ImageView element = (ImageView) findViewById(R.id.element);
            final ImageView name = (ImageView) findViewById(R.id.name);

            Button nextButton = (Button) findViewById(R.id.buttonNext);
            nextButton.setOnClickListener(new View.OnClickListener() {
                    public void onClick(View v) {
                            i++;

                            element.setImageResource(image_elements[i]);
                            name.setImageResource(image_names[i]);

                            i %= image_elements.length;
                    }
            });
    }
    public void backButton(View view) {
            Intent z = new Intent(this, MainMenuActivity.class);
            startActivity(z);
    }
}

回答1:

You'll need to rearrange your code from this:

                        i++;

                        element.setImageResource(image_elements[i]);
                        name.setImageResource(image_names[i]);

                        i %= image_elements.length;

to this:

                        i++;
                        i %= image_elements.length;

                        element.setImageResource(image_elements[i]);
                        name.setImageResource(image_names[i]);

What happens otherwise is that the index is incremented beyond the boundaries of the array, and that is corrected afterwards with the modulus operator. You'll need to the the correction before you use the index.

i %= image_elements.length in this particular case, is essentially the same as

if( i == image_elements.length ) {
    i = 0;
}

Arrays indices go from 0 to length-1.

You could get rid of the arrays entirely by looking up the resources by name, such as this:

final static int MAX_ELEMENTS = 88; // this includes 0..87
private int index = 0;

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.practice);

        final ImageView element = (ImageView) findViewById(R.id.element);
        final ImageView name = (ImageView) findViewById(R.id.name);
        final Resources res = this.getResources();
        final String pkgName = this.getPackageName();

        Button nextButton = (Button) findViewById(R.id.buttonNext);
        nextButton.setOnClickListener(new View.OnClickListener() {
                public void onClick(View v) {
                        final int imgId = res.getIdentifier( "spr_elements_" + index, "drawable", pkgName );
                        final int nameId = res.getIdentifier( "spr_name_" + index, "drawable", pkgName );
                        element.setImageResource( imgId );
                        name.setImageResource( nameId );

                        index = (index+1) % MAX_ELEMENTS;
                }
        });
}