-3

Hey I don't know why but this loop is not working and giving me same error every time. If you know the fix please answer it down. And I am not able fix the issue.

Here is my loop

double angle = 0;

for (int i = 0; i < 120; i++, angle += 3) {
    int x = (int) Math.ceil(i * 8.5);
    int t = ((byte) (-Math.abs(bytes[x]) + 128))
            * (canvas.getHeight() / 4) / 128;

    points[i * 4] = (float) (getWidth() / 2
            + radius
            * Math.cos(Math.toRadians(angle)));

    points[i * 4 + 1] = (float) (getHeight() / 2
             + radius
             * Math.sin(Math.toRadians(angle)));

    points[i * 4 + 2] = (float) (getWidth() / 2
            + (radius + t)
            * Math.cos(Math.toRadians(angle)));

    points[i * 4 + 3] = (float) (getHeight() / 2
            + (radius + t)
            * Math.sin(Math.toRadians(angle)));
}

Here is my error

E/AndroidRuntime: FATAL EXCEPTION: main

Process: app.androidgrid.faysr, PID: 19297

java.lang.ArrayIndexOutOfBoundsException: length=128; index=128
     at app.androidgrid.faysr.visualizer.view.CircleBarVisualizer.onDraw(CircleBarVisualizer.java:94)
     at android.view.View.draw(View.java:17096)
     at android.view.View.updateDisplayListIfDirty(View.java:16078)

I also tried changing 120 to 128 and i < 120 to i <= 120 but it's not

Here is my java class

public class CircleBarVisualizer extends BaseVisualizer {
private float[] points;
private Paint circlePaint;
private int radius;

public CircleBarVisualizer(Context context) {
    super(context);
}

public CircleBarVisualizer(Context context,
                           @Nullable AttributeSet attrs) {
    super(context, attrs);
}

public CircleBarVisualizer(Context context,
                           @Nullable AttributeSet attrs,
                           int defStyleAttr) {
    super(context, attrs, defStyleAttr);
}

@Override
protected void init() {
    paint.setStyle(Paint.Style.STROKE);
    circlePaint = new Paint();
    radius = -1;
}

@Override
protected void onDraw(Canvas canvas) {
    if (radius == -1) {
        radius = getHeight() < getWidth() ? getHeight() : getWidth();
        radius = (int) (radius * 0.65 / 2);
        double circumference = 2 * Math.PI * radius;
        paint.setStrokeWidth((float) (circumference / 120));
        circlePaint.setStyle(Paint.Style.STROKE);
        circlePaint.setStrokeWidth(4);
    }
    circlePaint.setColor(color);
    canvas.drawCircle(getWidth() / 2, getHeight() / 2, radius, circlePaint);
    if (bytes != null) {
        if (points == null || points.length < bytes.length * 4) {
            points = new float[bytes.length * 4];
        }
        double angle = 0;

        try {
            for (int i = 0; i < 120; i++, angle += 3) {
                int x = (int) Math.ceil(i * 8.5);
                int t = ((byte) (-Math.abs(bytes[x]) + 128))
                        * (canvas.getHeight() / 4) / 128;

                points[i * 4] = (float) (getWidth() / 2
                        + radius
                        * Math.cos(Math.toRadians(angle)));

                points[i * 4 + 1] = (float) (getHeight() / 2
                        + radius
                        * Math.sin(Math.toRadians(angle)));

                points[i * 4 + 2] = (float) (getWidth() / 2
                        + (radius + t)
                        * Math.cos(Math.toRadians(angle)));

                points[i * 4 + 3] = (float) (getHeight() / 2
                        + (radius + t)
                        * Math.sin(Math.toRadians(angle)));
            }
        } catch (ArrayIndexOutOfBoundsException e) {
            e.printStackTrace();
        }

        canvas.drawLines(points, paint);
    }
    super.onDraw(canvas);
}}

I am also try-catch so, it won't crash the app, but the result is not as I am excepting.

Ankit Suda
  • 128
  • 2
  • 9
  • 1
    The for loop iterates i from 0 to 119, but then the code uses multiples of i (`i * 4...`) to adress elements in the `points` array that is only 128 elements long (as the exception says). – david a. Jan 04 '18 at 12:58
  • 1
    You're accessing two arrays: `points[]` and `bytes[]`. The latter is indexed by `x` which is `ceil(i * 8.5)`. With `i == 15` the value of `x`will be 128 (`ceil(127.5)`) and also fits to your error message. Hence this could be a problem as well. – Ronald Jan 04 '18 at 13:01
  • one of your arrays has a length of 128, so your max index is 127, since you're zero indexed. your loop appears to result in you trying to access an element larger than the array size. try commenting out each array element call and see which one is triggering the error. your `Math.ceil(i * 8.5)` call is going to hit 128 when `i=15` – mal Jan 04 '18 at 13:04
  • @AnkitSuda make sure you upvote and accept the answer. – Ravi Jan 05 '18 at 03:29

4 Answers4

1

java.lang.ArrayIndexOutOfBoundsException: length=128; index=128 -> this means you are trying to access the 129th element of an array only containing 128 elements.

Remember, in Java arrays are 0 based, so the valid indices in your case vary from 0 to 127

Stultuske
  • 9,296
  • 1
  • 25
  • 37
1

For i = 0 ... 120, on the final iteration of your loop the following statement:

points[i * 4 + 3]

would be trying to access the 479th element of an array ((119 * 4) + 3 = 479) that only contains 128 elements.

In order to fill your array, you want i < 31 because (31 * 4) + 3 = 127.

Michael
  • 41,989
  • 11
  • 82
  • 128
0

Even you have for loop, which iterate for index 0 to 120, but inside your for loop you are trying to access different index (i * 4, i * 4 + etc), which is causing actual issue.

Imagine, you have points array of 2 size. Now, on first iteration, i would be 0, but you would be trying to access element i * 4 + 3, which would be equivalent to 3. But, points array size is 2.

Since, you are trying to access element i * 4 + 3 (which would be higher end in each iteration). I would suggest to change your for loop to something to avoid ArrayIndexOutOfBoundsException (if array size is 120)

 for (int i = 0; (i * 4 + 3) < 120; i++, angle += 3) {
Ravi
  • 30,829
  • 42
  • 119
  • 173
-1

You must review the size of the "points" array. Considering your code, its size should be at least (119 * 4 +3), i.e. 479.

"points" array size is 4 * "bytes" array size, but your code doesn't show what is the "bytes" array size; probably something defined in the ancestor class.