0

This is my MainActivity.java where I instanciate static SharedPreferences and it's editor:

public static SharedPreferences settings;
public static SharedPreferences.Editor editor;

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

    settings = PreferenceManager.getDefaultSharedPreferences(this);
    editor = settings.edit();

Then I make an AsyncTask call to another java class where I try to store a token in onPostExecute method to this SharedPreferences.

@Override
protected void onPostExecute(String result) {

    MainActivity.editor.putString("auth_token", result);
    MainActivity.editor.commit();

    Log.d("token", MainActivity.settings.getString("auth_token", "Nothing"));

}

This Log.d() method outprints the token value in the console, which is "OK". But then I start an acitivity Next.java where I try to get this token on a screen using this:

TextView text;

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

    String auth_token_string = MainActivity.settings.getString("auth_token", "Nothing");

    text = (TextView) findViewById(R.id.logintxt);
    text.setText(auth_token_string);

And the result on the screen is the default String "Nothing".

What am I doing wrong here? ...and is this the right way to use SharedPreferences? I got this idea here in this topic.

EDIT:

Code from AuthorizeActivity.java where I call the asyncTask:

 public void getToken(String code){

    AsyncTask<String, Void, String> tsk = new Api().execute(code);

    Intent i = new Intent(this.getBaseContext(), Next.class);
    dialog.dismiss();

    startActivity(i);

}
MoOoG
  • 293
  • 2
  • 5
  • 20
  • Could you post the complete code (where you call the asyncTask) ? – issathink Dec 21 '14 at 16:53
  • See you your `.commit()` call is returning `true` for successful save. You might try substituting `.commit()` for `apply()`. This won't return anything, by design, but is the method added since 2.3. – JASON G PETERSON Dec 21 '14 at 16:54
  • @issathink - I call asynctask from AuthorizeActivity.java - you can see the updated code above. – MoOoG Dec 21 '14 at 16:57
  • @JASONGPETERSON - for this reason I printed Log.d() where i get the value from "MainActivity.settings.getString("auth_token", "Nothing")". But anyways, the .commit() is returning true – MoOoG Dec 21 '14 at 16:59
  • I am pretty sure you are leaking your `Activity` by holding a static reference of an `Object` to which you are passing an instance of your `Activity`. Pass the `ApplicationContext` instead of `this`. – Emmanuel Dec 21 '14 at 17:28

3 Answers3

1

Your settings variable is static, it's initialised in onCreate method of MainActivity when you access settings in Next.java it's not initialised yet.

You have access to SharedPreferences in Next.java (it's shared).

EDIT :

add a update method in MainActivity :

public void update() {

  Intent i = new Intent(this.getBaseContext(), Next.class);

  startActivity(i);
}

and your postExecute should look like this :

 @Override
 protected void onPostExecute(String result) {

   MainActivity.editor.putString("auth_token", result);
   MainActivity.editor.commit();

   Log.d("token", MainActivity.settings.getString("auth_token", "Nothing"));
   ((MainActivity) context).update();

  }
issathink
  • 1,220
  • 1
  • 15
  • 25
  • I did the same in Next.java as in MainActivity.java using "this" for context initializing sharedPreferences but the result is still the default String. – MoOoG Dec 21 '14 at 17:13
  • 1
    Maybe your asyncTask is doing too much work, make Thread.sleep() untill your asyncTask finishes before accessing sharedPreferences – issathink Dec 21 '14 at 17:24
  • Yes, you are right! I put the Thread to sleep for 10 seconds and after that it printed out my token! Thank you for your answer How can I solve this by not putting Thread.sleep(3000) because on different devices it can need longer or shorter time? – MoOoG Dec 21 '14 at 17:34
  • Have a look at my answer. – issathink Dec 21 '14 at 17:47
  • 1
    The settings really should not be static and accessed across different Contexts – Ben Pearson Dec 21 '14 at 18:02
  • You're absolutely right @BenPearson! didn't pay attention, i used the "context" of his code. – issathink Dec 21 '14 at 18:07
0

Do not use the settings from MainActivity, create a new SharedPrefs instance and call getString method.

b4da
  • 3,010
  • 4
  • 27
  • 34
  • How do I do that? Because then somehow I need to get the same context which I used to instanciate the SharedPrefs to save the value to that activity where I want to read some values from SharedPrefs to instanciate it... Or am I wrong? – MoOoG Dec 21 '14 at 17:09
  • 1
    Use getApplicationContext() method to get the context. Every Activity in your app shares the same preferences. – b4da Dec 21 '14 at 17:13
  • I changed in MainActivity where I initialize the sharedPreferences "this" to "getApplicationContext()" and I initialized the sharedPrefs also in Next.java - the result is still the default String – MoOoG Dec 21 '14 at 17:16
  • In Next.java if you did this: SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); and if you still dont get the value problem is not sharedprefs. – b4da Dec 21 '14 at 17:24
0

Edit: I've created an example of how this should be handled on GitHub

Firstly, I would advise that you don't make your members static; they don't need to be static.

On your Next.class (Perhaps you should rename this, it's not clear what it does), you just need to get a handle on the shared preferences again with your new context:

PreferenceManager.getDefaultSharedPreferences(this);

Please note, there's a difference between getDefaultSharedPreferences and getSharedPreferences - use whichever you think it most appropriate.

Community
  • 1
  • 1
Ben Pearson
  • 7,532
  • 4
  • 30
  • 50
  • I already tried this, but I still get printed out the default String – MoOoG Dec 21 '14 at 17:18
  • To break down the problem, what happens if you commit the shared prefs and they try and read from it immediately (in the same activity)? – Ben Pearson Dec 21 '14 at 17:20
  • As you can see in the root question (look onPostExecute) I did read immediately from sharedPrefs and it prints out well what I need. This class where I extend asyncTask is seperate class (it's not innerclass of activity). – MoOoG Dec 21 '14 at 17:25
  • I created a couple of sample classes to show how it should be done and I've uploaded them to GitHub. Feel free to have a look, it should help – Ben Pearson Dec 21 '14 at 18:01
  • How do I find it on GitHub? – MoOoG Dec 21 '14 at 18:05
  • Sorry, I should have mentioned I edited my post with a link to it – Ben Pearson Dec 21 '14 at 18:09