2014-09-30 5 views
2

에 도달 할 경우 outofbounds 예외가 발생합니다. 이것은 장치의 최고 점수가 100 점을 초과하여 SharedPreferences에서 다음 번에 응용 프로그램이 충돌 할 때 응용 프로그램이 중단 될 때까지 완벽하게 작동합니다. 다음은 SharedPreferences에서 점수를 저장하고 검색하는 것과 관련된 코드입니다.Android 앱은 sharedpreferences에 높은 점수 값을 int로 저장합니다. 응용 프로그램은 100 개 이상의 점수가 나는 장치에 게임에 대한 높은 점수를 저장 된 SharedPreferences를 사용하는 안드로이드 게임을

public void setHighScore(int score) { 
    SharedPreferences.Editor settingsEditor = prefs.edit(); 
    settingsEditor.putInt(Constants.KEY_HIGHSCORE, score); 
    settingsEditor.commit(); 
    } 

public int getHighScore() { 
    return prefs.getInt(Constants.KEY_HIGHSCORE, 0); 
} 



if (score > activity.getHighScore()) { 
    activity.setHighScore(score); 
} 

     yourScoreText.setText("Your Score: " + score); 
     yourScoreText.setColor(Color.GREEN); 
     yourScoreText.setVisible(true); 

     highScoreText.setText("High Score: " + activity.getHighScore()); 
     highScoreText.setColor(Color.RED); 
     highScoreText.setVisible(true); 

로그 캣

09-19 22:00:13.612: W/dalvikvm(26458): threadid=12: thread exiting with uncaught exception (group=0x417a9898) 
09-19 22:00:13.622: E/AndroidRuntime(26458): FATAL EXCEPTION: UpdateThread 
09-19 22:00:13.622: E/AndroidRuntime(26458): java.lang.ArrayIndexOutOfBoundsException: length=360; index=360 
09-19 22:00:13.622: E/AndroidRuntime(26458): at org.andengine.entity.text.vbo.HighPerformanceTextVertexBufferObject.onUpdateVertices(HighPerformanceTextVertexBufferObject.java:124) 
09-19 22:00:13.622: E/AndroidRuntime(26458): at org.andengine.entity.text.Text.onUpdateVertices(Text.java:333) 
09-19 22:00:13.622: E/AndroidRuntime(26458): at org.andengine.entity.shape.Shape.setSize(Shape.java:146) 
09-19 22:00:13.622: E/AndroidRuntime(26458): at org.andengine.entity.text.Text.setText(Text.java:221) 
09-19 22:00:13.622: E/AndroidRuntime(26458): at hungryfish.scene.GameScene.reset(GameScene.java:246) 
09-19 22:00:13.622: E/AndroidRuntime(26458): at hungryfish.scene.GameScene.onSceneTouchEvent(GameScene.java:308) 
09-19 22:00:13.622: E/AndroidRuntime(26458): at org.andengine.entity.scene.Scene.onSceneTouchEvent(Scene.java:387) 
09-19 22:00:13.622: E/AndroidRuntime(26458): at org.andengine.engine.Engine.onTouchScene(Engine.java:470) 
09-19 22:00:13.622: E/AndroidRuntime(26458): at org.andengine.engine.Engine.onTouchEvent(Engine.java:456) 
09-19 22:00:13.622: E/AndroidRuntime(26458): at org.andengine.input.touch.controller.BaseTouchController$TouchEventRunnablePoolItem.run(BaseTouchController.java:102) 
09-19 22:00:13.622: E/AndroidRuntime(26458): at org.andengine.util.adt.pool.RunnablePoolUpdateHandler.onHandlePoolItem(RunnablePoolUpdateHandler.java:54) 
09-19 22:00:13.622: E/AndroidRuntime(26458): at org.andengine.util.adt.pool.RunnablePoolUpdateHandler.onHandlePoolItem(RunnablePoolUpdateHandler.java:1) 
09-19 22:00:13.622: E/AndroidRuntime(26458): at org.andengine.util.adt.pool.PoolUpdateHandler.onUpdate(PoolUpdateHandler.java:88) 
09-19 22:00:13.622: E/AndroidRuntime(26458): at org.andengine.input.touch.controller.BaseTouchController.onUpdate(BaseTouchController.java:62) 
09-19 22:00:13.622: E/AndroidRuntime(26458): at org.andengine.engine.Engine.onUpdate(Engine.java:604) 
09-19 22:00:13.622: E/AndroidRuntime(26458): at org.andengine.engine.LimitedFPSEngine.onUpdate(LimitedFPSEngine.java:57) 
09-19 22:00:13.622: E/AndroidRuntime(26458): at org.andengine.engine.Engine.onTickUpdate(Engine.java:568) 
09-19 22:00:13.622: E/AndroidRuntime(26458): at org.andengine.engine.Engine$UpdateThread.run(Engine.java:858) 
+1

나는 간단한 안드로이드 게임을 개발하고 높은 점수 같은 유지하고있다. 공유 환경 설정에서 100 개가 넘는 기록을 유지할 수 있습니다. 나는 오류가 응용 프로그램의 다른 곳이라고 생각합니다. – savepopulation

+2

전체 스택 추적을 표시하십시오. 그 순간 당신은 우리에게 * 어떻게 * 충돌하는지에 대해 아무 것도 말하지 않았습니다. 또한 코드 서식에 더 많은주의를 기울여주십시오. 들여 쓰기는 지금 곳곳에 있습니다. –

+0

내가 더보고 계속 하겠지만,이 점수가 100 이상 때까지 발생하지 않는 이상하다 – IrishCarBomb

답변

0

나는이 코멘트 것입니다하지만 난 점수에 50에서 해요 때문에 나는 간단한 해결책은 단지 문자열의 값을 저장하는 것입니다 .. 기운 다. 이처럼 :

SharedPreferences sp = getSharedPreferences(1); 
sp.edit().putString("highScore", String.valueOf(highScore)).apply 

을하고 공유 환경 설정에서 그것을 얻을 때 단지 개인적으로 내가 공유 환경 설정의 거대한 팬이 아니에요 대신 SQLite는 데이터베이스를 선택하는

int score = Integer.valueOf(sp.getString("highScore", "0")); 

을한다. 당신이 질문으로 나는,

.. .apply 백그라운드에서 실행 - 데이터베이스를 사용하는 경우 읽기/쓰기 순서는 당신이 시도 할 수

한 가지 .apply 대신 .commit의 사용이다 .. 훨씬 더 빨리 너무하다 데이터베이스에 도움이되도록 작성한 코드를 제공합니다. 방금 썼다 그것을 시도하고 그것을 작동하거나 적어도 내 GS3 (4.4.4) 및 내 OnePlus 하나 (4.4.4)에서 작동하는지.

나는 별도의 파일에서 클래스하지만 당신이 최대를 만들 것입니다. 예를 들어, 나는 단지 그것들을 내 기본 활동에서 사용하고 onCreate에서 일부 set/get 스코어 코드를 실행했습니다.

public class DatabaseHelper extends SQLiteOpenHelper{ 

    //final static stuff because you'll want to access it(the data) in other classes. 
    public static final String DB_NAME = "scores.db"; 
    public static final String SCORE_TABLE = "scores"; 
    public static final int VERSION = 3; 
    private Context context; 

    public DatabaseHelper(Context context){ 
     super(context, DB_NAME, null, VERSION); 
     this.context = context; 
    } 

    public SQLiteDatabase getDatabase(){ 
     return getWritableDatabase(); 
    } 

    @Override 
    public void onCreate(SQLiteDatabase db) { 
     //our code for creating the ScoreTable.. 
     db.execSQL("CREATE TABLE " 
       + SCORE_TABLE + 
       "(" + 
       "ID INT NOT NULL, " + 
       "Score INT);"); 
     //now we create one row of data. 
     db.execSQL("INSERT INTO " + DatabaseHelper.SCORE_TABLE + " (ID, Score) VALUES (1, 0);"); 
    } 

    @Override 
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 

     //if the version is greater than the previous one, we re-create it. 
     if(newVersion > oldVersion) { 
      db.execSQL("DROP TABLE IF EXISTS " + SCORE_TABLE); 
      onCreate(db); 
     } 
    } 
} 
public class DataSource{ 
    //this is a link between your app and the database. you don't have to use this. 
    private SQLiteDatabase database; 
    private Context context; 
    private DatabaseHelper helper; 
    public DataSource(Context context){ 
     //initiate our objects. 
     this.helper = new DatabaseHelper(context); 
     this.database = helper.getWritableDatabase(); 
     this.context = context; 
    } 

    public void setScore(int score){ 
     //we update the Score column where the ID is 1 
      database.execSQL("UPDATE " + DatabaseHelper.SCORE_TABLE + " SET Score = " + score + " WHERE ID = 1;"); 
    } 
    public int getScore(){ 
     //we get all of the columns that have a ID of one. There should only be one column. 
     Cursor score = database.rawQuery("SELECT * FROM " + DatabaseHelper.SCORE_TABLE + " WHERE ID = 1", null); 
     //this isn't especially needed, but i found that adding checks and balances keeps crashes down. 
     if(score.getColumnCount() < 1){ 
      return 0; 
     } else { 
      //this is important! You have to move the cursor to the first row. 
      score.moveToFirst(); 
      //now we get the data on row 1 (actually 2 if you look at it from a 1 based number system..) 
      int mscore = score.getInt(1); 
      //close the cursor 
      score.close(); 
      //and finally return the score. 
      return mscore; 
     } 
    } 

} 

위의 코드를 사용하려면 DataSource 개체를 만들고 setScore 및 getScore 메서드를 호출하십시오.

+0

나는 그것을 시도하고 어떻게되는지 볼 수 있습니다. sqllite db에 저장하는 것으로 변경하려면이 경우에이를 구현하는 방법에 대한 예제를 제공 할 수 있습니다. 나는 단지 높은 점수 만 저장할 필요가있다. – IrishCarBomb

+0

예. 내가 예를 올릴거야. – Seth

+0

고맙습니다. 나는 그것을 구현하여 내 문제를 해결하는지 확인하려고 노력할 것이다[email protected]는 전체 소스를보고이 기사에서 내가 놓친 것이 있는지 살펴 보는 데 관심이 있습니까? – IrishCarBomb