我的sharedprefs类名为UserData。
我可以为我的HUD调用一个int,它工作正常,就像这样
Text levelText = new Text(0, 40, AssetLoaderUtil.mFontMENU, "LEVEL: "
+ UserData.getInstance().getMaxUnlockedLevel(),
mContext.getVertexBufferObjectManager()){
@Override
protected void onManagedUpdate(float pSecondsElapsed) {
super.onManagedUpdate(pSecondsElapsed);
//This call to UserData works \/\/\/
this.setText("LEVEL: " + UserData.getInstance().getMaxUnlockedLevel());
}
};
但是在同一个班级,由于在UserData中调用添加到playerGold,这会导致应用程序崩溃。
mNPCSprite = new MyAnimatedSprite(310, 35,
AssetLoaderUtil.mPlayerTextureRegion, mContext) {
@Override
protected void onManagedUpdate(float pSecondsElapsed) {
super.onManagedUpdate(pSecondsElapsed);
if (mPlayerSprite.collidesWith(this)) {
mCurrentPlayerHealth -= 1;
//This call to UserData to add Gold, Crashes the app upon calling it.
//
//Leaving this line uncommented will crash app when i touch the NPC. \/\/\/
UserData.getInstance().addPlayerGold(15);
//yet, this toast, which gets a value from UserData, works fine \/\/\/
mContext.toastOnUIThread("Welcome to map1, Gold in UserData: "
+ UserData.getInstance().getPlayerGold(),
Toast.LENGTH_LONG);
// this.setIgnoreUpdate(true);
}
}
};
mNPCSprite.setZIndex(10);
this.attachChild(mNPCSprite);
/////////////////// 用户数据 //////////////////
package WorldScene.test.test;
import android.content.Context;
import android.content.SharedPreferences;
public class UserData {
private static UserData INSTANCE;
// Include a 'filename' for our shared preferences
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 = "unlockedLevels";
private static final String EXP_KEY = "playerExp";
private static final String SOUND_KEY = "soundKey";
private static final String PLAYER_GOLD = "playerGold";
/* Create our shared preferences object & editor which will
be used to save and load data */
private SharedPreferences mSettings;
private SharedPreferences.Editor mEditor;
// keep track of our max unlocked level
private int mUnlockedLevels;
// keep track of our max unlocked level
private int mPlayerExp;
// keep track of whether or not sound is enabled
private boolean mSoundEnabled;
// keep track of whether or not sound is enabled
private int mPlayerGold;
UserData() {
// The constructor is of no use to us
}
public synchronized static UserData getInstance() {
if(INSTANCE == null){
INSTANCE = new UserData();
}
return INSTANCE;
}
public synchronized void init(Context pContext) {
if (mSettings == null) {
/* Retrieve our shared preference file, or if it's not yet
* created (first application execution) then create it now
*/
mSettings = pContext.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
/* Define the editor, used to store data to our preference file
*/
mEditor = mSettings.edit();
/* Retrieve our current unlocked levels. if the UNLOCKED_LEVEL_KEY
* does not currently exist in our shared preferences, we'll create
* the data to unlock level 1 by default
*/
mUnlockedLevels = mSettings.getInt(UNLOCKED_LEVEL_KEY, 1);
/* Retrieve our current unlocked levels. if the UNLOCKED_LEVEL_KEY
* does not currently exist in our shared preferences, we'll create
* the data to unlock level 1 by default
*/
mPlayerGold = mSettings.getInt(PLAYER_GOLD, 0);
/* Retrieve our current unlocked levels. if the UNLOCKED_LEVEL_KEY
* does not currently exist in our shared preferences, we'll create
* the data to unlock level 1 by default
*/
mPlayerExp = mSettings.getInt(EXP_KEY, 1);
/* Same idea as above, except we'll set the sound boolean to true
* if the setting does not currently exist
*/
mSoundEnabled = mSettings.getBoolean(SOUND_KEY, true);
}
}
/* retrieve the max unlocked level value */
public synchronized int getMaxUnlockedLevel() {
return mUnlockedLevels;
}
/* retrieve the max unlocked level value */
public synchronized int getPlayerGold() {
return mPlayerGold;
}
/* retrieve the max unlocked level value */
public synchronized int getPlayerExp() {
return mPlayerExp;
}
/* retrieve the boolean defining whether sound is muted or not */
public synchronized boolean isSoundMuted() {
return mSoundEnabled;
}
/* This method provides a means to increase the max unlocked level
* by a value of 1. unlockNextLevel would be called if a player
* defeats the current maximum unlocked level
*/
public synchronized void unlockNextLevel() {
// Increase the max level by 1
mUnlockedLevels++;
/* Edit our shared preferences unlockedLevels key, setting its
* value our new mUnlockedLevels value
*/
mEditor.putInt(UNLOCKED_LEVEL_KEY, mUnlockedLevels);
/* commit() must be called by the editor in order to save
* changes made to the shared preference data
*/
mEditor.commit();
}
/* This method provides a means to increase the max unlocked level
* by a value of 1. unlockNextLevel would be called if a player
* defeats the current maximum unlocked level
*/
public synchronized void addPlayerGold(int g) {
// Increase the max level by 1
mPlayerGold += g;
/* Edit our shared preferences unlockedLevels key, setting its
* value our new mUnlockedLevels value
*/
mEditor.putInt(PLAYER_GOLD, mPlayerGold);
/* commit() must be called by the editor in order to save
* changes made to the shared preference data
*/
mEditor.commit();
}
public synchronized void addPlayerExp(int x) {
// Increase the max level by 1
mPlayerExp += x;
/* Edit our shared preferences unlockedLevels key, setting its
* value our new mUnlockedLevels value
*/
mEditor.putInt(EXP_KEY, mPlayerExp);
/* commit() must be called by the editor in order to save
* changes made to the shared preference data
*/
mEditor.commit();
}
/* The setSoundMuted method uses the same idea for storing new data
* into the shared preferences. First, we overwrite the mSoundEnabled
* boolean, use the putBoolean method to store the data, and finally
* commit the data to the shared preferences
*/
public synchronized void setSoundMuted(final boolean pEnableSound) {
mSoundEnabled = pEnableSound;
mEditor.putBoolean(SOUND_KEY, mSoundEnabled);
mEditor.commit();
}
}
//////////// logcat的 //////////
10-02 15:47:22.212: W/dalvikvm(848): threadid=11: thread exiting with uncaught exception (group=0x40fea2a0)
10-02 15:47:22.235: E/AndroidRuntime(848): FATAL EXCEPTION: UpdateThread
10-02 15:47:22.235: E/AndroidRuntime(848): java.lang.NullPointerException
10-02 15:47:22.235: E/AndroidRuntime(848): at WorldScene.test.test.UserData.addPlayerGold(UserData.java:143)
10-02 15:47:22.235: E/AndroidRuntime(848): at Scene.WorldScene$1.onManagedUpdate(WorldScene.java:115)
10-02 15:47:22.235: E/AndroidRuntime(848): at org.andengine.entity.Entity.onUpdate(Entity.java:1167)
10-02 15:47:22.235: E/AndroidRuntime(848): at org.andengine.entity.Entity.onManagedUpdate(Entity.java:1402)
10-02 15:47:22.235: E/AndroidRuntime(848): at org.andengine.entity.scene.Scene.onManagedUpdate(Scene.java:284)
10-02 15:47:22.235: E/AndroidRuntime(848): at org.andengine.entity.Entity.onUpdate(Entity.java:1167)
10-02 15:47:22.235: E/AndroidRuntime(848): at org.andengine.engine.Engine.onUpdateScene(Engine.java:604)
10-02 15:47:22.235: E/AndroidRuntime(848): at org.andengine.engine.Engine.onUpdate(Engine.java:599)
10-02 15:47:22.235: E/AndroidRuntime(848): at org.andengine.engine.LimitedFPSEngine.onUpdate(LimitedFPSEngine.java:51)
10-02 15:47:22.235: E/AndroidRuntime(848): at org.andengine.engine.Engine.onTickUpdate(Engine.java:561)
10-02 15:47:22.235: E/AndroidRuntime(848): at org.andengine.engine.Engine$UpdateThread.run(Engine.java:833)
10-02 15:47:22.251: W/ActivityManager(470): Force finishing activity WorldScene.test.test/.WorldActivity
如果从OnManagedUpdate调用,UserData中的unlockNextLevel()将使应用程序崩溃。 为什么我可以调用检查UserData中的变量,但不能更改它们?'
答案 0 :(得分:0)
感谢CaptainTeemo的答案!
对于有类似问题的人, 没有初始化UserData,不得不在WorldActivity中调用UserData.init():
@Override
protected Scene onCreateScene() {
this.getEngine().registerUpdateHandler(new FPSLogger());
// Initializes the Engine
mWorldEngine = this.getEngine();
//Start with touch enabled
TOUCH_ENABLED = true;
mMainCurtain = new Sprite(0, 0, AssetLoaderUtil.FadeTextureRegion, this.getVertexBufferObjectManager());
SceneManager.initialize(this);
SceneManager.mLoadingScene.create();
SceneManager.mGameIntroScene.create();
SceneManager.mMainMenuScene.create();
/////////////////////////
//ADDED SHAREDPREFS INIT() METHOD \/\/\/
////////////////////////
UserData.getInstance().init(getApplicationContext());
...
}