1

I'm attempting to load and save data using sharedpreferences in Kotlin, specifically using the Android Studio.

I'm getting this error message:

java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.SharedPreferences android.content.Context.getSharedPreferences(java.lang.String, int)' on a null object reference

Pointing at my initialization of shared preferences.

class MainActivity : AppCompatActivity(), SensorEventListener {

   private val dragonstats by lazy {getSharedPreferences("DRAGON_STATS",Context.MODE_PRIVATE)}

I get the same error if I write it this way:

val dragonstats = getSharedPreferences("DRAGON_STATS", Context.MODE_PRIVATE)

I've seen in other answers to declare it this way:

SharedPreferences dragonstats

but that doesn't read in Kotlin.

The android.com file on Shared preferences says to declare it this way:

val sharedPref = activity?.getSharedPreferences(
        getString(R.string.preference_file_key), Context.MODE_PRIVATE)

but that gives an unresolved reference error on activity.

How do I initialize a SharedPreferences file so I can store and retrieve data in Kotlin?


EDIT: So, the only thing that has worked to get it functional is to put ? in everything.

I declare it outside of oncreate so I can use it throughout:

var dragonstats: SharedPreferences? = null

in oncreate I set it:

dragonstats = PreferenceManager.getDefaultSharedPreferences(this)

Then, when I want to call any piece of it, I use ?:

exerciselevel = dragonstats?.getInt("exerciselevel", 0)!!

I don't understand why this works but nothing else does.

Siobhan S
  • 35
  • 1
  • 5

4 Answers4

3

I write it this way.

// in global
private lateinit var pref: SharedPreferences

override fun onCreate(savedInstanceState: Bundle?) {
    ...
      pref = getSharedPreferences("mysharedpref", Context.MODE_PRIVATE)
    ...
}

Jasper Calapini
  • 449
  • 4
  • 5
  • That doesn't work for me. I keep getting: Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference – Siobhan S Jun 27 '20 at 21:12
  • 2
    I just tried this answer and it works for me in Android Studio 4 – A.W. Oct 05 '20 at 16:32
-1

Try something like this to initialize preference:

val pref = PreferenceManager.getDefaultSharedPreferences(context) 

To read data:

pref.getString("your_key","default_value")

To save data:

pref.edit().putString("key","value").apply()

EDIT:

If you want to make your variable global you can do something like this:

lateinit var pref:SharedPreferences

and then in onCreate() :

pref = PreferenceManager.getDefaultSharedPreferences(context) 
Rejfin
  • 1
  • 1
  • That gets the same error: Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference – Siobhan S Jun 24 '20 at 21:25
  • Do you call initialization in onCreate() method? – Rejfin Jun 24 '20 at 21:30
  • I'm trying to have the SharedPreferences value be available across all functions, so I'm trying to declare it outside of the oncreate function. I'm a bit of a beginner and I can't seem to figure out how to do this. – Siobhan S Jun 24 '20 at 21:42
-1

I just started learning Android and Kotlin and the answer suggested by Jasper Calapini works for me in Android Studio 4

private lateinit var pref: SharedPreferences

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        pref = getSharedPreferences("myPref", Context.MODE_PRIVATE)
        var name: String? = pref.getString("my-string", "hello")

        val editor = pref.edit()
        editor.putString("my-string", "value is changed")
        editor.apply()

        println("name = ${name}")  
 }  
A.W.
  • 2,858
  • 10
  • 57
  • 90
-1

As the error says, you get a NullPointerException because the Context is null. You can of course use this, but be aware that the keyword this is implicit:

private val dragonstats by lazy {getSharedPreferences("DRAGON_STATS",Context.MODE_PRIVATE)}
//equivalent to
private val dragonstats by lazy {this.getSharedPreferences("DRAGON_STATS",Context.MODE_PRIVATE)}

[this,] it's the context of current state of the application/object. It lets newly-created objects understand what has been going on. Typically you call it to get information regarding another part of your program (activity and package/application). See the full answer on SO

There is only one condition to respect in order not to obtain a NullPointerException: you must have a context of the application/activity. To do this, don't forget to call this.setContentView(R.layout.main) in your OnCreate() method (again, the keyword this is not necessary and may be implicit) which will create the context you are looking for. In other words, it will "initialize" the application context this.

If you need SharedPreferences outside of an activity, take a look at this answer.

I think the private val pref by lazy {} is the best for the use (because val, not var, and is initialized in one line of code), but make sure you call this.setContentView(R.layout.main) before using pref

TheBigBadBoy
  • 611
  • 5
  • 14