How to pass application context from Singleton class to SharedPreferences? I have a fragment and a GridView inside its onActivityCreated(Bundle savedInstanceState) method , on item-click, I am getting NullPointerException in logcat:
03-30 05:12:54.784: E/AndroidRuntime(1950): FATAL EXCEPTION: main
03-30 05:12:54.784: E/AndroidRuntime(1950): java.lang.NullPointerException
03-30 05:12:54.784: E/AndroidRuntime(1950): at android.preference.PreferenceManager.getDefaultSharedPreferencesName(PreferenceManager.java:374)
03-30 05:12:54.784: E/AndroidRuntime(1950): at android.preference.PreferenceManager.getDefaultSharedPreferences(PreferenceManager.java:369)
03-30 05:12:54.784: E/AndroidRuntime(1950): at com.example.duaapp.utility.SharedPreferencesSupplication.save(SharedPreferencesSupplication.java:35)
Singleton Class
public class SingletonClass {
public static Context applicationContext;
public static int fontSizeMin = 17;
public static int fontSizeMax = 35;
public static final String keySelVerseFromList = "keySelVerseFromList";
public static final String keyFavVerses = "keyFavVerses";
public static final String keyListOfVerses = "keyListOfVerses";
public static final String keyIsFavSelected = "keyIsFavSelected";
}
SharedPreferences
public class SharedPreferencesSupplication {
public void save(String valueKey, String value) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(SingletonClass.applicationContext);
SharedPreferences.Editor edit = prefs.edit();
edit.putString(valueKey, value);
edit.commit();
}
public void save(String valueKey, int value) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(SingletonClass.applicationContext);
SharedPreferences.Editor edit = prefs.edit();
edit.putInt(valueKey, value);
edit.commit();
}
public void save(String valueKey, boolean value) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(SingletonClass.applicationContext);
SharedPreferences.Editor edit = prefs.edit();
edit.putBoolean(valueKey, value);
edit.commit();
}
public void save(String valueKey, long value) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(SingletonClass.applicationContext);
SharedPreferences.Editor edit = prefs.edit();
edit.putLong(valueKey, value);
edit.commit();
}
}
On gridview_item_Click, whenever new SharedPreferencesSupplication().save(SingletonClass.keyIsFavSelected, false); is called, the app crashes and nullpointer exception is raised in logcat. Where am I going wrong?
Never use static references to Context in Android, this will cause you an important memory leak since Context has references to all the application resources.
Most of the Android UI classes have a dynamic reference to the context, in fragments you can do getActivity()
, in views getContext()
consider using those instead of context singletons
More information about this here
While Guillermo Merino concern is valid, an application Context
used in a singleton class should not be automatically considered a memory leak.
Calling context.getApplicationContext()
will, regardless of where or how it is accessed, always return the same instance from within your process. It will be "alive" for at least as long as the singleton will, therefore holding a reference to it should do no harm.
That said, it might not be enough to perform certain operations, as Dave Smith describes in his blog post.
Since OP is trying to access default SharedPreferences
, this could be achieved using just application Context
, e.g.:
// Custom Application class.
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
SingletonClass.INSTANCE.init(getApplicationContext());
}
}
// Singleton.
public enum SingletonClass {
INSTANCE;
private Context applicationContext;
public static int fontSizeMin = 17;
public static int fontSizeMax = 35;
public static final String keySelVerseFromList = "keySelVerseFromList";
public static final String keyFavVerses = "keyFavVerses";
public static final String keyListOfVerses = "keyListOfVerses";
public static final String keyIsFavSelected = "keyIsFavSelected";
// Make sure you only call this once - from MyApplication.
public void init(final Context context) {
applicationContext = context.getApplicationContext();
}
public Context getApplicationContext() {
if (null == applicationContext) {
throw new IllegalStateException("have you called init(context)?");
}
return applicationContext;
}
}
I don't believe this would cause any memory leaks, but if I'm mistaken, please do correct me.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With