Search code examples
javaandroidsharedpreferences

SharedPreferences not Save if the application is re-open


My sharedpreferences does not save if i re-open my game the data that i saved before with SharedPreferences are not load, setting on my current activity is back to normal again or default

this is the image of my button in menu.class

enter image description here

this is the following code of my menu.class

@Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
    WindowManager.LayoutParams.FLAG_FULLSCREEN);
    setContentView(R.layout.menu);
    SharedPreferences pref = getSharedPreferences("SavedGame", MODE_PRIVATE); 
    SharedPreferences.Editor editor = pref.edit();      
    editor.putInt("Lifes", 6);
    editor.putInt("Hints", 6);          
    editor.putInt("Level", 1);  
    editor.commit();

     f1=(Button)findViewById(R.id.f1);

     f2=(Button)findViewById(R.id.f2);
     f2lock=(ImageView)findViewById(R.id.f2lock);


   f1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v){
                // TODO Auto-generated method stub
                Intent i =new Intent(menu.this, levelone.class);
                startActivity(i);             
            }             
        }); 

    f2.setOnClickListener(new View.OnClickListener() {

         @Override
         public void onClick(View v){
           // TODO Auto-generated method stub
              Intent i =new Intent(menu.this, leveltwo.class);
              startActivity(i);          
            }             
      });

    f3=(Button)findViewById(R.id.f3);
    f3lock=(ImageView)findViewById(R.id.f3lock);

}
public void onResume() {
super.onResume();

   SharedPreferences pref = getSharedPreferences("SavedGame", MODE_PRIVATE); 
   levelunlocked = pref.getInt("Level", 0); 

   if(levelunlocked == 2)

    {
        f2.setVisibility(View.VISIBLE);
        f2lock.setVisibility(View.GONE);
    }
    if(levelunlocked == 3)

    {
        f3.setVisibility(View.VISIBLE);
        f3lock.setVisibility(View.GONE);
    }   

       SharedPreferences.Editor editor = pref.edit();
       editor.putInt("Level", levelunlocked);
       editor.commit();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.splashscreen, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();
    if (id == R.id.action_settings) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}
}

and i had this code in levelone.class to get the default value from menu.class

int gamelifes, gamehints, gamelevel, index=0; 


SharedPreferences pref = getSharedPreferences("SavedGame", MODE_PRIVATE);
gamelifes = pref.getInt("Lifes", 0);
gamehints = pref.getInt("Hints", 0);
gamelevel = pref.getInt("Level", 0);

//the value from sharedpreferences is use to be a text by use code below

lifes1 =(TextView)findViewById(R.id.lifestext1);
lifes1.setTextColor(Color.RED);
lifes1.setText(String.valueOf(gamelifes));   

hints1 =(TextView)findViewById(R.id.hintstext1);
hints1.setTextColor(Color.GRAY);
hints1.setText(String.valueOf(gamehints));

and to save the sharedpreferences with new data

String answer=edittextanswer1.getText().toString();              
            if(answer.equalsIgnoreCase(answer1[index]))
            {
                gamelevel++;                
                image.setVisibility(View.GONE); 
                finishbutton.setVisibility(View.VISIBLE);  
                SharedPreferences pref = getSharedPreferences("SavedGame", MODE_PRIVATE); 
                SharedPreferences.Editor editor = pref.edit();      
                editor.putInt("Lifes", gamelifes);
                editor.putInt("Hints", gamehints);          
                editor.putInt("Level", gamelevel);  
                editor.commit();
            else
            {    
            tryagain1.setVisibility(View.VISIBLE);
            gamelifes--;
            lifes1.setText(String.valueOf(gamelifes));
            }

then if finish button is clicked it will be like this

finishbutton.setOnClickListener(new View.OnClickListener() {

      public void onClick(View v){
          finish();
      }
   }); 

so levelone.class are finish and back to menu.class

enter image description here

and SharedPreferences code its worked properly, every button in my menu.class work with the code and be visible!

but if i exit the application, its back to normal again

enter image description here

anyone have a solution to fix my problem here?


Solution

  • Thing is, on your onCreate() method you're always resetting the shared preferences here:

    SharedPreferences pref = getSharedPreferences("SavedGame", MODE_PRIVATE); 
    SharedPreferences.Editor editor = pref.edit();      
    editor.putInt("Lifes", 6);
    editor.putInt("Hints", 6);          
    editor.putInt("Level", 1);  
    editor.commit();
    

    Just check if this file exists already before that line with an if statement. That should do the trick.

    Something like:

    if (pref.contains("Level")) {
        // Do not reset
    }
    else {
        // Create the prefs
        SharedPreferences.Editor editor = pref.edit();      
        editor.putInt("Lifes", 6);
        editor.putInt("Hints", 6);          
        editor.putInt("Level", 1);  
        editor.commit();
    }
    

    You don't have to check for that exact field, it's just an example. Adjust it for your needs and game logic.

    Take a look at the Activity lifecycle to understand why this is happening.

    enter image description here

    (diagram source)

    Everytime you open your app, the onCreate() method is called, so your prefs get reset before you read them.

    More on the lifecycle here.

    EDIT: The following snippet shows one way to solve your problem.

    public static final String PREF_LIFES = "Lifes";
    public static final String PREF_HINTS = "Hints";
    public static final String PREF_LEVEL = "Level";
    public static final String PREF_IS_SET = "isSet";
    
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
        WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.menu);
    
        SharedPreferences pref = getSharedPreferences("SavedGame", MODE_PRIVATE); 
    
        // Check wether the pref is set or not.
        if (pref.getBoolean(PREF_IS_SET.false)) {
            // The prefs is set. Do some game logic here. Like checking for lifes.
            if (pref.getInt(PREF_LIFES,0) == 0) {
                // Player is "dead", reset it.
                resetPrefs(pref); 
            }
            else {
                // Player is alive, do whatever you want, or do nothing at all.
            }
        }
        else {
            // if it's not set, just create it.
            resetPrefs(pref);
        }
    
        // ...   
    }
    
    private void resetPrefs(SharedPreferences pref) {
        SharedPreferences.Editor editor = pref.edit();      
        editor.putInt(PREF_LIFES, 6);
        editor.putInt(PREF_HINTS, 6);          
        editor.putInt(PREF_LEVEL, 1);
        editor.putBoolean(PREF_IS_SET,true);
        editor.commit();
    }
    

    EDIT 2: You can put this logic on your onResume() method as well, as long as you remove it from the onCreate(), otherwise you'll be checking those conditions twice ;)