2

(I know final can't be changed. But if you read the example I have typed, you can understand why I am asking this question!)

I am reading the example hello world Android app:

MainActivity.java

public final static String EXTRA_MESSAGE = "com.example.helloworld.MESSAGE";
....
....
intent.putExtra(EXTRA_MESSAGE, message);

How does it work? Are we storing the message value in EXTRA_MESSAGE?

Additionally, how many SharedPreferences can I have to store data? Assuming that, my app needs to store the levels and high scores, how do I do that?

public final static String HIGH_SCORE = "com.example.helloworld.HIGH_SCORE";
public final static String LEVELS = "com.example.helloworld.LEVELS";

SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putInt(getString(R.string.saved_high_score), newHighScore);
editor.commit();

How do I change the above lines to save the levels and scores?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Prabha Vathi
  • 347
  • 1
  • 4
  • 10
  • 2
    You are not storing anything into `EXTRA_MESSAGE`. The `intent` object is storing `message` and using `EXTRA_MESSAGE` as a key. So the stored `message` can then later be accessed through `intent` by querying it for `EXTRA_MESSAGE`. – SamYonnou Sep 05 '13 at 15:17
  • "final" it self describe that it can not change. – Hardik Joshi Sep 05 '13 at 15:17
  • @SamYonnou Thanks.. Then, What is the purpose of "com.example.helloworld.MESSAGE"? – Prabha Vathi Sep 05 '13 at 15:19
  • 3
    [Enjoy!](http://stackoverflow.com/questions/3301635/change-private-static-final-field-using-java-reflection) – Sotirios Delimanolis Sep 05 '13 at 15:19
  • @PrabhaVathi see updated answer understand what's going on with intent – Trikaldarshiii Sep 05 '13 at 15:29
  • @PrabhaVathi The purpose of that string is to act like a key (as I described). The reason it is set to that value instead of just something like "key" is so that it hopefully does not collide with any other keys. If all the keys you used were just "key" then you could ever only store one value. – SamYonnou Sep 05 '13 at 15:49

6 Answers6

3

When in doubt, check the docs:

The static modifier, in combination with the final modifier, is also used to define constants. The final modifier indicates that the value of this field cannot change.

What's defined here:

public final static String EXTRA_MESSAGE = "com.example.helloworld.MESSAGE";

is a constant meant to remain like that, otherwise, you can see the bugs comming here:

intent.putExtra(EXTRA_MESSAGE, message);

if Extra_MESSAGE were to change, the Entry that has its previous value as a key could end up "lost" (inaccessible, to be more precise, because you didn't save that value somewhere else).

In order to save further info, you'll need more keys for the map. This means that your correctly defined fields here:

public final static String HIGH_SCORE = "com.example.helloworld.HIGH_SCORE";
public final static String LEVELS = "com.example.helloworld.LEVELS";

Can be used to store those values in the given map, or wherever you want to use them as a identifier (bases on a key-value structure). The concept here is that you have to define a constant accessible through the game in order to be able to store AND retrieve the data.

Fritz
  • 9,987
  • 4
  • 30
  • 49
0

No you cannot change the value once assigned. That is why it's called final. You can have many preferences as you want as they are just files.

intent.putExtra(EXTRA_MESSAGE, message);

Think of a map. It's just a key-value relationship. EXTRA_MESSAGE is the key and message is the value.

To put, you do-

preferences.edit().putString("name", "adam");

To get, you can use the key you used-

preferences.getString("name", "none"); 

Tutorials and References:

Shared Preferences

Vogella

Sajal Dutta
  • 18,272
  • 11
  • 52
  • 74
0

EDIT 1:

Your question is too different from the original question. This is because you are just misunderstanding it.

MainActivity.java

public final static String EXTRA_MESSAGE = "com.example.helloworld.MESSAGE";
....
....
intent.putExtra(EXTRA_MESSAGE, message);

This piece of code does not mean that EXTRA_MESSAGE is storing message now. It's something like a key/value pair.

It means:

Intent is storing the value of a message with a key named value of EXTRA_MESSAGE, so if you pass a value of EXTRA_MESSAGE to an intent, it will give a value to message.

final is fixed. It never, never changes its value, so that it's called FINAL.

And nor you can change it. It is always treated as a constant.

See final (Java) on Wikipedia for more help.

Community
  • 1
  • 1
Trikaldarshiii
  • 11,174
  • 16
  • 67
  • 95
  • 1
    I think you need to be careful here. If people believe too strongly in the guarentees of final, they are sure to be confused/disappointed at some point. If the datatype is mutable, then the data can certainly be changed, just not the reference. – Cruncher Sep 05 '13 at 15:21
0

This line:

intent.putExtra(EXTRA_MESSAGE, message)

means that you're storing the message's value in the Intent's internal map under the EXTRA_MESSAGE key. It does not change in any way content of the EXTRA_MESSAGE variable.

Damian Jeżewski
  • 1,246
  • 2
  • 14
  • 21
0

An Intent has a Bundle within it, which holds parameters to be passed on. Think of this as a mapping, so when you write

intent.putExtra(EXTRA_MESSAGE, message);

it saves message into a field named by EXTRA_MESSAGE.

So, if you want to store the highscore and level use:

public final static String HIGH_SCORE = "com.example.helloworld.HIGH_SCORE";
public final static String LEVELS = "com.example.helloworld.LEVELS";

SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putInt(HIGH_SCORE, newHighScore);
editor.putInt(LEVELS, level);
editor.commit();

Note that if you write into HIGH_SCORE or LEVELS again, it will override the current value!

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
krishan711
  • 873
  • 1
  • 12
  • 27
  • This answer doesn't make it clear that the value of the `final static` variables are not being overwritten. – GriffeyDog Sep 05 '13 at 15:23
  • Her question title is just badly worded, if you read the question you will realise she doesn't want to know how EXTRA_MESSAGE or any other variable declared final can be changed. She wants to know how to save to shared preferences! – krishan711 Sep 05 '13 at 15:26
  • @krishan711 I wanted to know how they can be changed too! You answered to my questions anyway. I thought, EXTRA_MESSAGE = 'my new message' when the intend started to carry my message. I understand it now! – Prabha Vathi Sep 05 '13 at 16:02
  • ah my bad @GriffeyDog. glad your question was answered, don't forget to accept an answer! – krishan711 Sep 05 '13 at 16:04
  • @krishan711 When i reopen the app, can i get the values of HIGH_SCORE and LEVELS? – Prabha Vathi Sep 05 '13 at 16:06
  • You get them using: SharedPreferences prefs = getActivity().getPreferences(Context.MODE_PRIVATE); int highScore = prefs.getInt(HIGH_SCORE, 0); int level = prefs.getInt(LEVELS, 0); where 0 is the default value – krishan711 Sep 05 '13 at 16:06
0
  1. Can I change a final variable?

As you have said, and as you know this too, we can't change final values normally, but using a reflection API this may be possible, see this an answer to Stack Overflow question Change private static final field using Java reflection.

  1. How is this stored intent.putExtra(EXTRA_MESSAGE, message); ?

As many of the answers have said, putExtra works in a way of WAP, where a specific key is mapped to a specific value of type string, integer, etc. So, in this case EXTRA_MESSAGE acts as the key, while the message acts as value.

  1. How many values can I add to SharedPreferences?

AFAIK, there is no limit on how many SharedPreferences you can add, it depends on you, but as SharedPreferences are mostly related to application settings, although, not explicitly required, but we can opt for storing large or personal application data to an XML file or to databases.

  1. How can I save my code to store a specific value?

    editor.putInt(getString(R.string.saved_high_score), newHighScore);
    

    Assuming newHighScore is the value you want to store, you may opt to change getString(R.string.saved_high_score) to a more specific key like Level Number, so that when you next time update it, the score will automatically get overwritten.

Community
  • 1
  • 1
Rachit Mishra
  • 6,101
  • 4
  • 30
  • 51