-2

This is the save() method in my app:

public void save() {
    Context context;
    SharedPreferences sp = context.getSharedPreferences("gameSave",
            Context.MODE_PRIVATE);
    SharedPreferences.Editor editor = sp.edit();

    editor.putInt("X", player.getX());
    editor.putInt("Y", player.getY());
    editor.putInt("level", player.getLevel());
    editor.putFloat("xp", player.getXp());
    editor.commit();
}

I have been trying to get this to work for a while now, but the getSharedPreferences (String name, int mode) has not been working for me. It doesn't come up on it's own, context.getSharedPreferences() works, but that yields a NullPointerException, I think because of my context. I have tried save(Context context){} as a constructor, but calling that from another method with context declared inside of that method does not work either. I've looked at many examples, but none of them have worked for me. So how can I get getSharedPreferences() to work?

EDIT: I have a class GameScreen and a class SaveManager. When I save in Gamescreen this is the code I use:

Savemanager savemanager;
savemanager.save();
state = GameState.Running;

And I have my class SaveManager:

package com.package.game;

import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;

public class SaveManager extends Activity {

private Player player = GameScreen.getPlayer();

public void save() {
    SharedPreferences sp = getSharedPreferences("gameSave",
            Context.MODE_PRIVATE);
    SharedPreferences.Editor editor = sp.edit();

    editor.putInt("X", player.getX());
    editor.putInt("Y", player.getY());
    editor.putInt("level", player.getLevel());
    editor.putFloat("xp", player.getXp());
}
}

And when I save in GameScreen my app crashes and I get this logcat:

02-20 01:39:31.979: E/AndroidRuntime(1368): FATAL EXCEPTION: Thread-119
02-20 01:39:31.979: E/AndroidRuntime(1368): java.lang.NullPointerException
02-20 01:39:31.979: E/AndroidRuntime(1368): at com.package.game.GameScreen.updateLevelUp(GameScreen.java:364)

Line 364 is the line savemanager.save();. I have no idea why this crashes my app.

user2005938
  • 159
  • 2
  • 2
  • 14
  • 2
    *"not been working for me"* please be more specific. Your code up there uses a `null` Context, but you mention this is only *one* of your trials. – A--C Feb 19 '13 at 22:57
  • Is this inside of an activity? – dymmeh Feb 19 '13 at 22:58
  • @A--C, getSharedPreferences() is not recognized as a method by itself. In almost every example I've seen that method is by itself and in some examples it is context.getSharedPreferences(), and neither of those work for me. How should I use context instead? – user2005938 Feb 19 '13 at 23:40
  • You never initialize your context, so it is defaulting to null, and calling getSharedPreferences on your unitialized, null, context will always throw an NPE. Assuming you are in an activity, you would use this.getSharedPreferences(). – Brent Hronik Feb 19 '13 at 23:54
  • @BrentHronik this.getSharedPreferences() still says that the method getSharedPreferences is undefined. – user2005938 Feb 20 '13 at 01:00
  • Are you calling it within an inner class of the activity? – Brent Hronik Feb 20 '13 at 01:05

1 Answers1

6

getSharedPreferences() is a Context method. If save() is in a class that extends Context, such as Activity, you don't have to do context.getSharedPreferences(), so you can do, as you put it "the method by itself".

However, if save isn't in a class that extends Context, for it to be able to call getSharedPreferences(), it needs to have a Context variable passed off. This means that what you were doing by simply making a context variable isn't enough (and that code shouldn't compile, there would be an error thrown about how the context variable hasn't been initialized). And since Contexts aren't made using a constructor, your method hits a dead end.

However, you are close. For the sake of explanation, you can make a static method that accepts in a Context and does the saving. static since this method really shouldn't need an object instance, it can be self-contained:

public static void save(Context context) {

    if (context == null)
      throw new RuntimeException ("Context is null, what are you doing?");

    SharedPreferences sp = context.getSharedPreferences("gameSave",
            Context.MODE_PRIVATE);
    SharedPreferences.Editor editor = sp.edit();

    editor.putInt("X", player.getX());
    editor.putInt("Y", player.getY());
    editor.putInt("level", player.getLevel());
    editor.putFloat("xp", player.getXp());
    editor.commit();
}

Now if this method was part of a class for example named StaticUtils, you can call save:

  • Through an Activity: StaticUtils.save(YourActivityClass.this); or StaticUtils.save(this); depending on the scope (eg if inside an anonymous inner function, you'd use YourActivityClass.this).
  • Fragment: StaticUtils.save(getActivity());
  • BroadcastReceiver: StaticUtils.save(context);
  • A View (eg the View passed on when onClick() is called: StaticUtils.save(v.getContext());

Just keep in mind that the earilest you can do saving in an Activity is onCreate() anything before will fail and the Exception should clearly indicate that.

A simple demo. No extending anything, no fancy making of Context:

MainActivity.java:

public class MainActivity extends Activity {
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

     StaticUtils.save(this);

     SharedPreferences prefs = getSharedPreferences ("gameSave", Context.MODE_PRIVATE);
     System.out.println ("X is " + prefs.getInt ("X",-1));
  }
}

StaticUtils.java

public class StaticUtils {
    public static void save(Context context) {

        if (context == null)
          throw new RuntimeException ("Context is null, what are you doing?");

        SharedPreferences sp = context.getSharedPreferences("gameSave",
                Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();

        editor.putInt("X", 11);
        editor.putInt("Y", 24);
        editor.putInt("level", 3);
        editor.putFloat("xp", 100);
        editor.commit();
    }
}
A--C
  • 36,351
  • 10
  • 106
  • 92
  • Thanks, and how should I call this method from another method? Would something like `Context context; save(context);` work? – user2005938 Feb 20 '13 at 00:31
  • Absolutely not, as I said in my answer: *This means that what you were doing by simply making a context variable isn't enough*. You have to understand just declaring a variable *doesn't* suddenly make it contain something. You need a [*valid*](http://stackoverflow.com/questions/3572463/what-is-context-in-android) Context. All the ways to call the method in my answer should theoretically provide valid Contexts. – A--C Feb 20 '13 at 00:33
  • If I am using the method you have above, none of the ways to call save(Context context) work for me. I am calling it from within the same class. If I make another class called SaveManager that extends Context and call it from another class I get Cannot make a static reference to the non-static method save() from the type SaveManager, and changing the modifier of save() to static makes the whole method not work. Thanks for all of your help so far, and sorry for the trouble. – user2005938 Feb 20 '13 at 00:58
  • @user2005938 edited my answer, with a demo. Please make sure that MainActivity is defined in your xml. As I have hinted in my answer, each class is in its own file. – A--C Feb 20 '13 at 01:07
  • could you take a look at my edit? I have no idea what I am doing wrong, it's probably something really basic, I'm fairly new to android programming as you might of guessed. Thank you _so_ much for your help so far, I really appreciate it. – user2005938 Feb 20 '13 at 01:50
  • No, you're new to java. Asking *why* a `null` variable throws an NPE when you try to do something with it shows your current skill level. So please follow the Java tutorials, get a grip on Java, then follow the Android tutorials. ***Then*** once you've done all that, here's my hint: Storing instances of an Activity is usually bad, instantiating it is worse. – A--C Feb 20 '13 at 01:52