-1

I'm trying to use SharedPreferences in a non activity class from onResume() in an activity but I'm getting a NullPointerException on the context.

For some reason I cannot get the context in onResume(). Not sure if I'm missing something, but any help would be appreciated.

onResume() Method in my activity

@Override
protected void onResume() {
    super.onResume();
    // The activity has become visible (it is now "resumed").

    // Check User's Access Token exists and hasn't expired.
    AccountFunctions accountFunctions = new AccountFunctions();

    if (!accountFunctions.validateUserToken(this)) {
        Intent intent = new Intent(this, LoginActivity.class);
        startActivity(intent);
    }
}

validateUserToken(Context context) method in AccountFunctions Class

public Boolean validateUserToken(Context context) {

    SharedPreferences sharedPref = context.getSharedPreferences(getString(R.string.user_file_key), Context.MODE_PRIVATE); // This is where the error is thrown
    String accessToken = sharedPref.getString(getString(R.string.user_access_token), null);
    DateTime expiryDate = new DateTime(sharedPref.getLong(getString(R.string.user_expires), 0));

    if (accessToken == null || expiryDate.isBeforeNow()) {
        return false;
    } else {
        return true;
    }
}

The Error

java.lang.RuntimeException: Unable to resume activity {uk.co.itsstonbury.www.intouch/uk.co.itsstonbury.www.intouch.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.content.Context.getApplicationContext()' on a null object reference

Pavneet_Singh
  • 36,884
  • 5
  • 53
  • 68
Richard McKenna
  • 213
  • 4
  • 25
  • 1
    Your issue is that `AccountFunctions` appears to extend some `Context` or `Activity` class, and it really shouldn't. – OneCricketeer Nov 30 '16 at 18:06
  • 2
    I wouldn't consider this a duplicate of the one linked. My question is to do with a problem with the context as solved by the answer below. Don't think it warrants a down vote. – Richard McKenna Nov 30 '16 at 18:43

2 Answers2

3

replace getString(R.str with context.getString because AccountFunctions class has not been created by the OS so it doesn't have it's own context ready.

Basically activity gets it's context form application when oncreate function get called by OS callbacks since it's not gonna happen in this case so AccountFunctions object will not have it's own context

This code simply assume that AccountFunctions will be created normally through intent but in this case it is like a simple class object which has no connection with activity life-cycle calls.

so your code will look like

public Boolean validateUserToken(Context context) {

    SharedPreferences sharedPref = context.getSharedPreferences(context.getString(R.string.user_file_key), Context.MODE_PRIVATE); // This is where the error is thrown
    String accessToken = sharedPref.getString(context.getString(R.string.user_access_token), null);
    DateTime expiryDate = new DateTime(sharedPref.getLong(context.getString(R.string.user_expires), 0));

    if (accessToken == null || expiryDate.isBeforeNow()) {
        return false;
    } else {
        return true;
    }
}

or you can use string values directly

    SharedPreferences sharedPref = context.getSharedPreferences("yourkey", Context.MODE_PRIVATE); // This is where the error is thrown

or

The better option is create a separate Util class for helper function rather like

class Util{

    public static boolean validateUserToken(Context context) {

        SharedPreferences sharedPref = context.getSharedPreferences(context.getString(R.string.user_file_key), Context.MODE_PRIVATE); // This is where the error is thrown
        String accessToken = sharedPref.getString(context.getString(context.R.string.user_access_token), null);
        DateTime expiryDate = new DateTime(sharedPref.getLong(context.getString(R.string.user_expires), 0));

        if (accessToken == null || expiryDate.isBeforeNow()) {
            return false;
        } else {
            return true;
        }
    }
}

from your activity call it like

 Util.validateUserToken(this);
Pavneet_Singh
  • 36,884
  • 5
  • 53
  • 68
  • @cricket_007 this `getString(context.R.s` will try to find and use the `AccountFunctions` activity context which is not there because OP just created the object – Pavneet_Singh Nov 30 '16 at 18:07
  • Yeah, I commented above. `getString` shouldn't even be a directly accessible method of that class – OneCricketeer Nov 30 '16 at 18:08
  • @cricket_007 since `AccountFunctions` is an activity so subtle issue in this case :P – Pavneet_Singh Nov 30 '16 at 18:09
  • I'm just saying that it appears to be a static helper / utility class. If it did extend `Activity`, then it doesn't need to. And if it didn't, then `getString` isn't an available method – OneCricketeer Nov 30 '16 at 18:12
  • @cricket_007 i know and yeah it could be a helper class , but we can't see what else is there – Pavneet_Singh Nov 30 '16 at 18:15
  • 1
    Great answer, thank you. Yes it is a helper class but I was extending Application which was my problem and changing to `context.getstring` it now works as expected. – Richard McKenna Nov 30 '16 at 18:38
  • @RichardMcKenna i am glad i could help and thank you for the compliment :) – Pavneet_Singh Nov 30 '16 at 18:46
0

Replace SharedPreferences sharedPref = context.getSharedPreferences(getString(R.string.user_file_key), Context.MODE_PRIVATE); with
SharedPreferences sharedPref = context.getSharedPreferences(context.getString(R.string.user_file_key), Context.MODE_PRIVATE);

Ratna Halder
  • 1,954
  • 16
  • 17