Stitches S
Stitches S

Reputation: 65

Understanding SharedPreferences

I have been looking for some help with SharedPreferences(SP) but find myself more and more confused. My understanding was that, by default, using the package name in the declaration of SP would make the preferences available throughout all activities in my app.

Since searching stack overflow, I have noticed the use of filenames (I have searched my app folders extensively for any kind of SP files to no avail), where would these be stored? I have also noticed the use of so-called 'singleton methods'.

The source of my issue is the following code -

MainActivity -

public class MainActivity extends AppCompatActivity {

SharedPreferences sharedPreferences;
SharedPreferences.Editor editor;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    setTitle("Let's Play Darts");

    sharedPreferences = getApplicationContext().getSharedPreferences("com.app.letsplaydarts", Context.MODE_PRIVATE);
    editor = sharedPreferences.edit(); // package name used in declaration as I was taught

    editor.putString("p1", null);
    editor.putInt("p1Picked", 0);
    editor.putString("p2", null);
    editor.putInt("p2Picked", 0);     // Resetting values when app opens
    editor.putString("p3", null);
    editor.putInt("p3Picked", 0);
    editor.putString("p4", null);
    editor.putInt("p4Picked", 0);

    editor.commit();

}
}

clicking a button opens - GameSetup activity - editor unused in this activity

public class GameSetup extends AppCompatActivity {

SharedPreferences sharedPreferences;
SharedPreferences.Editor editor;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_game_setup);

sharedPreferences = getApplicationContext().getSharedPreferences("com.app.letsplaydarts", Context.MODE_PRIVATE);
editor = sharedPreferences.edit(); // declared in same manner

    if (sharedPreferences.getInt("p1Picked", 0) == 1) {

        player1TextView.setText(sharedPreferences.getString("p1", ""));

        if (sharedPreferences.getInt("p2Picked", 0) == 1) {

            player2TextView.setText(sharedPreferences.getString("p2", ""));

            if (sharedPreferences.getInt("p3Picked", 0) == 1) {

                player3TextView.setText(sharedPreferences.getString("p3", ""));

                if (sharedPreferences.getInt("p4Picked", 0) == 1) {

                    player4TextView.setText(sharedPreferences.getString("p4", ""));

                }
            }
        } // sets textviews dependant on SP values
    }

    Log.d("testing", "p1Picked " + sharedPreferences.getInt("p1Picked", 0));
    Log.d("testing", "p1" + sharedPreferences.getString("p1", ""));
    Log.d("testing", "p2Picked " + sharedPreferences.getInt("p2Picked", 0));
    Log.d("testing", "p2" + sharedPreferences.getString("p2", ""));
    Log.d("testing", "p3Picked " + sharedPreferences.getInt("p3Picked", 0));
    Log.d("testing", "p3" + sharedPreferences.getString("p3", ""));
    Log.d("testing", "p4Picked " + sharedPreferences.getInt("p4Picked", 0));
    Log.d("testing", "p4" + sharedPreferences.getString("p4", ""));

} // on first run through, all logs are defaults reset in MainActivity

Clicking a button in the GameSetup activity calls a .java class to open an alert dialog with a listview to select from a list of players retrieved from a ParseServer -

    public void selectionDialog (View view) {

    CustomMethods.playerSelection(this);

}

calls -

public class CustomMethods {

    static public String playerSelection (final Context context) {

    final SharedPreferences sharedPreferences = context.getApplicationContext().getSharedPreferences("com.apps.letsplaydarts", Context.MODE_PRIVATE);
    final SharedPreferences.Editor editor = sharedPreferences.edit(); // same declaration again - declared final for access in listeners

// alert dialog code removed

playerListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

                if (position == 0) {

                    Intent intent = new Intent(context, AddPlayer.class);
                    intent.putExtra("callingIntent", "Setup");
                    context.startActivity(intent);

                } else {

                    playerToReturn[0] = playerList.get(position);

                    if (sharedPreferences.getInt("p1Picked", 0) == 0) {

                        editor.putInt("p1Picked", 1);
                        editor.putString("p1", playerToReturn[0]);

                    } else {

                        if (sharedPreferences.getInt("p2Picked", 0) == 0) {

                            editor.putInt("p2Picked", 1);
                            editor.putString("p2", playerToReturn[0]);

                        } else {

                            if (sharedPreferences.getInt("p3Picked", 0) == 0) {

                                editor.putInt("p3Picked", 1);
                                editor.putString("p3", playerToReturn[0]);

                            } else {

                                if (sharedPreferences.getInt("p4Picked", 0) == 0) {

                                    editor.putInt("p4Picked", 1);
                                    editor.putString("p4", playerToReturn[0]);

                                }
                            }
                        }
                    }

                    editor.apply();

                    Log.d("testing", "p1Picked " + sharedPreferences.getInt("p1Picked", 0));
                    Log.d("testing", "p1" + sharedPreferences.getString("p1", ""));
                    Log.d("testing", "p2Picked " + sharedPreferences.getInt("p2Picked", 0));
                    Log.d("testing", "p2" + sharedPreferences.getString("p2", ""));
                    Log.d("testing", "p3Picked " + sharedPreferences.getInt("p3Picked", 0));
                    Log.d("testing", "p3" + sharedPreferences.getString("p3", ""));
                    Log.d("testing", "p4Picked " + sharedPreferences.getInt("p4Picked", 0));
                    Log.d("testing", "p4" + sharedPreferences.getString("p4", ""));


                    Intent intent = new Intent(context, GameSetup.class);
                    intent.putExtra("callingIntent", "Select");
                    intent.putExtra("playerReturned", playerToReturn[0]);
                    context.startActivity(intent);

                }

                Log.i("Position Selected", Integer.toString(position));

            }
        });

Now... the coding itself functions, the appropriate SPs are set before leaving the alert dialog but when returning to the GameSetup Activity and the logs are checked again, it only shows the same default values logged as the logs before leaving GameSetup and not the ones saved while running the alert dialog.

Am I completely misunderstanding how SP works? Or is it the Context.MODE_PRIVATE that I haven't seen used in other examples that needs changing. I have spent a long time looking into this without gaining a greater understanding of the SP functionality but from what I was taught, this should work.

I'd very much appreciate some assistance with this matter. Thanks.

AFTERTHOUGHT EDIT - could it be the contexts creating the problem as I'm running the code in a separate .java class? would my problem be solved running the alert dialog code direct from the GameSetup activity? My reasoning for using the .java class is for the ability to call from other activities.

As requested Logs - loading GameSetup from MainActivity

11-01 19:55:44.449 22498-22498/com.app.letsplaydarts D/testing: p1Picked 0
11-01 19:55:44.449 22498-22498/com.app.letsplaydarts D/testing: p1
11-01 19:55:44.449 22498-22498/com.app.letsplaydarts D/testing: p2Picked 0
11-01 19:55:44.449 22498-22498/com.app.letsplaydarts D/testing: p2
11-01 19:55:44.449 22498-22498/com.app.letsplaydarts D/testing: p3Picked 0
11-01 19:55:44.449 22498-22498/com.app.letsplaydarts D/testing: p3
11-01 19:55:44.449 22498-22498/com.app.letsplaydarts D/testing: p4Picked 0
11-01 19:55:44.449 22498-22498/com.app.letsplaydarts D/testing: p4

after player selection in .java class alert dialog -

these are NOT reset by the onCreate of MainActivity
11-01 19:55:50.168 22498-22498/com.app.letsplaydarts D/testing: p1Picked 1
11-01 19:55:50.168 22498-22498/com.app.letsplaydarts D/testing: p1[Les]
11-01 19:55:50.168 22498-22498/com.app.letsplaydarts D/testing: p2Picked 1
11-01 19:55:50.169 22498-22498/com.app.letsplaydarts D/testing: p2[Iain]
11-01 19:55:50.169 22498-22498/com.app.letsplaydarts D/testing: p3Picked 1
11-01 19:55:50.169 22498-22498/com.app.letsplaydarts D/testing: p3[Les]
11-01 19:55:50.169 22498-22498/com.app.letsplaydarts D/testing: p4Picked 1
11-01 19:55:50.169 22498-22498/com.app.letsplaydarts D/testing: p4[Les]

after returning to GameSetup from .java class alert dialog

11-01 19:55:50.212 22498-22498/com.app.letsplaydarts D/testing: p1Picked 0
11-01 19:55:50.212 22498-22498/com.app.letsplaydarts D/testing: p1
11-01 19:55:50.212 22498-22498/com.app.letsplaydarts D/testing: p2Picked 0
11-01 19:55:50.212 22498-22498/com.app.letsplaydarts D/testing: p2
11-01 19:55:50.212 22498-22498/com.app.letsplaydarts D/testing: p3Picked 0
11-01 19:55:50.212 22498-22498/com.app.letsplaydarts D/testing: p3
11-01 19:55:50.212 22498-22498/com.app.letsplaydarts D/testing: p4Picked 0
11-01 19:55:50.212 22498-22498/com.app.letsplaydarts D/testing: p4

SOLVED - was due to a typo in one of my SP declarations. I'm fairly new to the community so please advise as to whether I should delete this question or leave it in case anyone else has the issue. For the record, I have learned a fair bit from this posting. Thanks.

Upvotes: 2

Views: 83

Answers (1)

Martin Zeitler
Martin Zeitler

Reputation: 76679

These are located in /data/data/tld.domain.package/shared_prefs/*.xml and in .onCreate(Bundle savedInstanceState), check for savedInstanceState == null

... in order to determine when the Activity is being launched - because .onCreate(Bundle savedInstanceState) runs more often than once, which is a common source of confusion. Just set a break-point into there and see what it does when returning to this Activity. The documentation of SharedPreferences and SharedPreferences.Editor explains it pretty well - and one can also listen for changes elsewhere with: registerOnSharedPreferenceChangeListener().

Upvotes: 5

Related Questions