Rahul bhardwaj
Rahul bhardwaj

Reputation: 15

How to solve java.lang.IndexOutOfBoundsException: Invalid index 24, size is 21

When I add more than 21 question to my question app and try to run it, I get the following error:

12-13 13:18:12.384 21277-21277/com.example.chaitanya.myquiz E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.chaitanya.myquiz, PID: 21277
java.lang.IndexOutOfBoundsException: Invalid index 24, size is 21
 at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
 at java.util.ArrayList.get(ArrayList.java:308)
 at com.example.chaitanya.myquiz.QuestionActivity.getAnswer(QuestionActivity.java:121)
 at com.example.chaitanya.myquiz.QuestionActivity$3.onClick(QuestionActivity.java:90)
 at android.view.View.performClick(View.java:4759)
 at android.view.View$PerformClick.run(View.java:19770)
 at android.os.Handler.handleCallback(Handler.java:739)
 at android.os.Handler.dispatchMessage(Handler.java:95)
 at android.os.Looper.loop(Looper.java:135)
 at android.app.ActivityThread.main(ActivityThread.java:5237)
 at java.lang.reflect.Method.invoke(Native Method)
 at java.lang.reflect.Method.invoke(Method.java:372)
 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:912)
 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:707)

Here is the extract from the java file in which I store my questions where the error occurs:

//There are 30 question in the database
public List<Question> getAllQuestions() {
List<Question> quesList = new ArrayList<Question>();
// Select All Query
String selectQuery = "SELECT  * FROM " + TABLE_QUEST;
dbase = this.getReadableDatabase();
Cursor cursor = dbase.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
    do {
        Question quest = new Question();
        quest.setID(cursor.getInt(0));
        quest.setQUESTION(cursor.getString(1));
        quest.setANSWER(cursor.getString(2));
        quest.setOPTA(cursor.getString(3));
        quest.setOPTB(cursor.getString(4));
        quest.setOPTC(cursor.getString(5));
        quesList.add(quest);
    } while (cursor.moveToNext());
}
// return quest list
return quesList;
}

And here is the QuestionActivity class that is used in my code for the questions:

//QuestionActivity class
import java.util.List;
import java.util.Random;
import java.util.Timer;
import java.util.concurrent.TimeUnit;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Typeface;
import android.media.MediaPlayer;
import android.os.Build;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class QuestionActivity extends Activity {
    List<Question> quesList;
    int score = 0;
    Random r = new Random();
    int qid =0;

    Question currentQ;
    TextView txtQuestion, times, scored;
    Button button1, button2, button3;
    CounterClass timer;


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

    QuizHelper db = new QuizHelper(this);  // my question bank class
    quesList = db.getAllQuestions();  // this will fetch all Q  
    currentQ = quesList.get(qid); // the current question

    txtQuestion = (TextView) findViewById(R.id.txtQuestion);
    // the textview in which the question will be displayed

    // the three buttons,
    button1 = (Button) findViewById(R.id.button1);
    button2 = (Button) findViewById(R.id.button2);
    button3 = (Button) findViewById(R.id.button3);

    // the textview in which score will be displayed
    scored = (TextView) findViewById(R.id.score);

    // the timer
    times = (TextView) findViewById(R.id.timers);

    // method which will set the things up for our game
    setQuestionView();
    times.setText("00:00:30");
    timer = new CounterClass(30000, 1000);
    timer.start();

    // button click listeners
    button1.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // passing the button text to other method
            // to check whether the anser is correct or not
            // same for all three buttons
            getAnswer(button1.getText().toString());
        }
    });

    button2.setOnClickListener(new View.OnClickListener() {
        @Override
            public void onClick(View v) {
            getAnswer(button2.getText().toString());
        }
    });

    button3.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            getAnswer(button3.getText().toString());
        }
    });
}

public void getAnswer(String AnswerString) {
    if (currentQ.getANSWER().equals(AnswerString)) {
        // if conditions matches increase the int (score) by 1
        // and set the text of the score view
        score++;
        scored.setText("Score : "+ score);
    } else {
        // if unlucky start activity and finish the game
        timer.cancel();
        Intent intent = new Intent(QuestionActivity.this,
                ResultActivity.class);

        // passing the int value
        Bundle b = new Bundle();
        b.putInt("score", score); // Your score
        intent.putExtras(b); // Put your score to your next
        startActivity(intent);
        finish();
    }
    if (qid < 31) {
        // if questions are not over then do this
        currentQ = quesList.get(qid);
        setQuestionView();
    } else {
        // if over do this
        Intent intent = new Intent(QuestionActivity.this,
                ResultActivity.class);
        Bundle b = new Bundle();
        b.putInt("score", score); // Your score
        intent.putExtras(b); // Put your score to your next
        startActivity(intent);
        finish();
    }
}

@TargetApi(Build.VERSION_CODES.GINGERBREAD)
@SuppressLint("NewApi")
public class CounterClass extends CountDownTimer {
    public CounterClass(long millisInFuture, long countDownInterval) {
        super(millisInFuture, countDownInterval);
        // TODO Auto-generated constructor stub
    }
    @Override
    public void onFinish() {
        times.setText("Time is up");
        Intent intent = new Intent(QuestionActivity.this,
                ResultActivity.class);
        Bundle b = new Bundle();
        b.putInt("score", score); // Your score
        intent.putExtras(b); // Put your score to your next
        startActivity(intent);
        finish();
    }
    @Override
        public void onTick(long millisUntilFinished) {
        // TODO Auto-generated method stub

        long millis = millisUntilFinished;
        String hms = String.format(
                "%02d:%02d:%02d",
                TimeUnit.MILLISECONDS.toHours(millis),
                TimeUnit.MILLISECONDS.toMinutes(millis)
                        - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS
                        .toHours(millis)),
                TimeUnit.MILLISECONDS.toSeconds(millis)
                        -TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS
                        .toMinutes(millis)));
        System.out.println(hms);
        times.setText(hms);
    }
}
private void setQuestionView() {
    // the method which will put all things together
    txtQuestion.setText(currentQ.getQUESTION());
    button1.setText(currentQ.getOPTA());
    button2.setText(currentQ.getOPTB());
    button3.setText(currentQ.getOPTC());
    qid= (r.nextInt(30) + 20);
}

Upvotes: 1

Views: 2589

Answers (2)

SachinSarawgi
SachinSarawgi

Reputation: 2692

xEception: java.lang.IndexOutOfBoundsException: Invalid index 24, size is 21 occurs when you try to access index which does not exists.

Here in this case quesList size is 21 as mentioned in the exception but you are trying to access 24th index which gives the exception.

The main problem lies in this if (qid < 31) {. Here you are making it constant to make your program work for variable number of question returned from the database modify it as if (qid < quesList.size()) {.

In this it does not matter whether you have 21 or any other number of question, your program will work properly.

Upvotes: 1

Manohar
Manohar

Reputation: 23404

The error says every thing ,

java.lang.IndexOutOfBoundsException: Invalid index 24, size is 21

your array size is only 21 and your are trying to access 24th element of array

i guess the problem is some where at line button1 or 2 or 3, the button has text 23

also button1.getText().toString() gives string but index should be integer so do

int i= Integer.parseInt(button1.getText().toString());

and also remove any value on button greater that 23

better check if value exists first then try to access it

 if(getAnswer.size()>i){

     getAnswer(i);
 }

similarly for other too

Upvotes: 1

Related Questions