我正在开发Andengine for Android的游戏。我决定使用SharedPreferences来保存levelunlock数据,高分数据等等。我实现了保存数据,但是当我再次打开游戏时,它正在重新设置数据以初始化数据。这就是为什么即使用户传递了一些数据也会锁定所有级别的原因。
我使用这个类:
package com.example.aaa.extras;
import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;
public class UserData {
private static UserData INSTANCE;
private static final String PREFS_NAME = "GAME_USERDATA";
/* These keys will tell the shared preferences editor which data we're trying to access */
private static final String UNLOCKED_LEVEL_KEY = "GAME_USERDATA";
private static final String SOUND_KEY = "soundKey";
//private static final String LIFE = "playerHealth";
private static final String HIGHSCORE = "GAME_USERDATA";
private static final String EDITED[] = {"GAME_USERDATA", "GAME_USERDATA", "GAME_USERDATA", "GAME_USERDATA", "GAME_USERDATA", "GAME_USERDATA"};
/* Create our shared preferences object and editor which will be used to save and load data */
private SharedPreferences mSettings;
private SharedPreferences.Editor mEditor;
//keep track of max unlocked level
public int mUnlockedLevel = 1; //public int mUnlockedLevel = 5;
//keep track of player high score
public int mHighScore = 0;
public boolean mEditedLevel[] = {false, false, false, false, false, false};
//keep track of player health
//public int health = 100;
//keep track of whether or not not sound is enabled
private boolean mSoundEnabled;
UserData() {
}
public synchronized static UserData getInstance() {
if (INSTANCE == null){
INSTANCE = new UserData();
Log.v("","Creates a new instance of UserData");
}
Log.v("","returns the instance of UserData");
return INSTANCE;
}
public synchronized void init(Context pContext){
if (mSettings == null){
mSettings = pContext.getSharedPreferences(PREFS_NAME, pContext.MODE_PRIVATE);
mEditor = mSettings.edit();
mUnlockedLevel = mSettings.getInt(UNLOCKED_LEVEL_KEY, 1);
mHighScore = mSettings.getInt(HIGHSCORE, 0);
mSoundEnabled = mSettings.getBoolean(SOUND_KEY, true);
for(int i=0;i<6;i++)
mEditedLevel[i] = mSettings.getBoolean(EDITED[i], false);
Log.v("","Set up initial values for UserData " + mUnlockedLevel + " " + mHighScore + " " + mSoundEnabled);
}
}
public synchronized int getMaxUnlockedLevel() {
return mUnlockedLevel;
}
public synchronized boolean isSoundMuted() {
return mSoundEnabled;
}
public synchronized int getHighScore() {
Log.v("","HighScore before increment " + mHighScore);
return mHighScore;
}
public synchronized boolean getEdited(int i) {
Log.v("","mEditedLevel before increment " + mEditedLevel[i]);
return mEditedLevel[i];
}
public synchronized void unlockNextLevel() {
mUnlockedLevel++;
mEditor.putInt(UNLOCKED_LEVEL_KEY, mUnlockedLevel);
mEditor.commit();
}
public synchronized void setSoundMuted(final boolean pEnableSound){
mSoundEnabled = pEnableSound;
mEditor.putBoolean(SOUND_KEY, mSoundEnabled);
mEditor.commit();
}
public synchronized void setHighScore(final int newHighScore){
mHighScore = newHighScore;
Log.v("","mHighScore is " + mHighScore);
mEditor.putInt(HIGHSCORE, mHighScore);
mEditor.commit();
}
public synchronized void setEdited(int i, final boolean newEdited){
mEditedLevel[i] = newEdited;
Log.v("","mEditedLevel is " + mEditedLevel[i]);
mEditor.putBoolean(EDITED[i], mEditedLevel[i]);
mEditor.commit();
}
}
我在startActivity(第一个活动)中创建并初始化(),如下所示:
public void onCreateScene(OnCreateSceneCallback pOnCreateSceneCallback) throws IOException
{
SceneManager.getInstance().createSplashScene(pOnCreateSceneCallback);
UserData userData = UserData.getInstance();
userData.init(this);
}
我在任何需要使用的类中都使用它:
UserData.getInstance().setEdited(0, true);
UserData.getInstance().getEdited(0));
答案 0 :(得分:0)
内部初始化方法:Context.MODE_PRIVATE
mSettings = pContext.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
并删除编辑()而不是阅读,仅用于写作:
mEditor = mSettings.edit();
答案 1 :(得分:0)
SharedPreferences是键值/值对的Map,您不能拥有重复键。您对许多项目使用相同的密钥,因此稍后只会写入一个键/值对:
private static final String UNLOCKED_LEVEL_KEY = "GAME_USERDATA";
private static final String SOUND_KEY = "soundKey";
private static final String HIGHSCORE = "GAME_USERDATA";
private static final String EDITED[] = {"GAME_USERDATA", "GAME_USERDATA", "GAME_USERDATA", "GAME_USERDATA", "GAME_USERDATA", "GAME_USERDATA"};
然后,在第一次运行时,使用默认值初始化设置 - 因为您尚未编写它们(请参阅代码中的注释):
public synchronized void init(Context pContext){
if (mSettings == null){
//use static Context.MODE_PRIVATE, instead pContext.MODE_PRIVATE
//as an argument in getSharedPreferences
mSettings = pContext.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
mEditor = mSettings.edit();
//same key used for level, highscore, and editedlevel
//which means all these variables will have the same value determined by "GAME_USERDATA" key
mUnlockedLevel = mSettings.getInt(UNLOCKED_LEVEL_KEY, 1);
mHighScore = mSettings.getInt(HIGHSCORE, 0);
mSoundEnabled = mSettings.getBoolean(SOUND_KEY, true);
for(int i=0;i<6;i++)
mEditedLevel[i] = mSettings.getBoolean(EDITED[i], false);
Log.v("","Set up initial values for UserData " + mUnlockedLevel + " " + mHighScore + " " + mSoundEnabled);
}
}
我没有看到任何后来提交这些值的代码,所以如果它丢失了(例如你没有使用mEditor.commit()),它们将始终获得默认值。
此外,如第一段所述,对于使用GAME_USERDATA的项目,设置中只有一个键/值对。
将您的密钥更改为唯一:
private static final String UNLOCKED_LEVEL_KEY = "unlocked_level_key";
private static final String SOUND_KEY = "soundKey";
private static final String HIGHSCORE = "highscore";
private static final String EDITED[] = {"ed1", "ed2", "ed3", "ed4", "ed5", "ed6"};
然后在想要将每个变量的不同值保存到设置文件中时调用unlockNextLevel(),setSoundMuted(),setHighScore(),setEdited(),下次在init()期间,您将获得值为他们得救了。