0

Im trying to store the top 5 high scores inside a sharedpreference instead of an sqlite database. So I looked around and found two methods (saveArray and loadArray) from a stack post here ( Is it possible to add an array or object to SharedPreferences on Android )

Anyway when I try and add in a value to the array I get an arrayoutofbounds error. java.lang.ArrayIndexOutOfBoundsException: length=0;index=0

Because the user will not start with values in the array I'm trying to determine if the array has a value at position i, If not I am trying to insert the score that was passed into the array at that position. But it won't work and I'm not sure why?

So essentially if highscores[i] != null then I'll go and check to see if highscores[i] < intScore, if highscores is < intScore then I will replace it with the passed score in the constructor.

String[] highscores = new String[5];

public void editHighscores(String score){
    int intScore = Integer.parseInt(score);


    highscores = loadArray("highscores",this.getApplicationContext());

    // Checks to see if index is empty
    for(int i=0;i<5; i++){
        if(highscores[i] == null){
            highscores[i] = score;
        } else{
            if(Integer.parseInt(highscores[i]) < intScore){
                highscores[i] = score;
            }
        }

        Log.d("index - " + i, "Value = " + highscores[i]);
    }
    // Save the array
    saveArray(highscores, "highscores", this.getApplicationContext());




}
public boolean saveArray(String[] array, String arrayName, Context mContext) {   
    SharedPreferences prefs = mContext.getSharedPreferences("highscoresPref", 0);  
    SharedPreferences.Editor editor = prefs.edit();  
    editor.putInt(arrayName +"_size", array.length);  
    for(int i=0;i<array.length;i++)  
        editor.putString(arrayName + "_" + i, array[i]);  
    return editor.commit();  
} 

public String[] loadArray(String arrayName, Context mContext) {  
    SharedPreferences prefs = mContext.getSharedPreferences("highscoresPref", 0);  
    int size = prefs.getInt(arrayName + "_size", 0);  
    String array[] = new String[size];  
    for(int i=0;i<size;i++)  
        array[i] = prefs.getString(arrayName + "_" + i, null);  
    return array;  
}  
Community
  • 1
  • 1
James111
  • 15,378
  • 15
  • 78
  • 121
  • 1
    I think you need to change **int size = prefs.getInt(arrayName + "_size", 0);** to **int size = prefs.getInt(arrayName + "_size", 5);** – Dhaval Patel Nov 16 '15 at 05:15

3 Answers3

0

try this code

String[] highscores = new String[5];

  public void editHighscores(String score){
int intScore = Integer.parseInt(score);


highscores = loadArray("highscores",this.getApplicationContext());

 if(highscores!=null && highscroes.length>0)
     {
    // Checks to see if index is empty
      for(int i=0;i<5; i++){
       if(highscores[i] == null){
           highscores[i] = score;
       } else{
        if(Integer.parseInt(highscores[i]) < intScore){
            highscores[i] = score;
        }
    }

    Log.d("index - " + i, "Value = " + highscores[i]);
}
// Save the array
saveArray(highscores, "highscores", this.getApplicationContext());


   }

  }
Meenal
  • 2,879
  • 5
  • 19
  • 43
  • Wouldn't this just prevent any data from ever being saved into the array? Because I'm starting with an empty shared preference, meaning it will always be null or the length will always be 0 unless I can access that for loop to insert data into the array. – James111 Nov 16 '15 at 05:39
  • No..because..you are editing saved list...first time you will save list using saveArray..then you will call edit..right? – Meenal Nov 16 '15 at 05:43
0

In the loadArray() method, size defaults to 0. On your first run, there won't be any saved preference, so the size is 0, and this is what you're using to dimension the array.

Since you're checking for null values in the editHighscores() method, you don't need to track the size. You've already decided how big the array should be: 5.

Mike M.
  • 38,532
  • 8
  • 99
  • 95
  • Ah, I understand. So I can just take out the size altogether from the loadArray() method? – James111 Nov 16 '15 at 05:30
  • What I did was replace the `size variable` in the `loadArray()` method with a static value of 5. Instead of having it statically declared I could simply add another argument to the constructor. – James111 Nov 16 '15 at 05:38
  • 1
    I would just make it a constant: `private static final int HIGH_SCORE_COUNT = 5;`. Then you only have to change that one value should you ever decide to track, say, the top ten scores. – Mike M. Nov 16 '15 at 05:40
0

Initially int size = prefs.getInt(arrayName + "_size", 0); will return size 0 as array size is not stored.

So, loadArray method will return empty Array..

In your editHighscores method you are trying to insert score on empty array which will produce ArrayIndexOutOfBoundsException.

So as work around Replace int size = prefs.getInt(arrayName + "_size", 0); with int size = prefs.getInt(arrayName + "_size", 5);

Dhaval Patel
  • 10,119
  • 5
  • 43
  • 46