The app uses a singleton GameStorage
to save some settings for the users. It works fine on emulators and my own devices, but from Google Play I got several crash reports lateinit property prefs has not been initialized
.
There are four reports, from Android 8.0 to 13.0.
The singleton is initialized in MainActivity when the app starts
GameStorage.shared.init(applicationContext)
And call the method in GameActivity:
if (GameStorage.shared.isSoundOn) {
// ...
}
Singleton:
class GameStorage private constructor() : Activity() {
private object HOLDER {
val SHARED = GameStorage()
}
companion object {
val shared: GameStorage by lazy { HOLDER.SHARED }
}
private lateinit var prefs: SharedPreferences
private val prefsName = "GameStorage"
fun init(context: Context) {
prefs = context.getSharedPreferences(prefsName, Context.MODE_PRIVATE)
}
private fun read(key: String, defaultValue: Boolean): Boolean {
return prefs.getBoolean(key, defaultValue)
}
fun write(key: String, value: Boolean) {
val prefsEditor: SharedPreferences.Editor = prefs.edit()
with(prefsEditor) {
putBoolean(key, value)
commit()
}
}
var isSoundOn: Boolean
get() {
return read("isSoundOn", true)
}
set(value) {
write("isSoundOn", value)
}
// ...
}
This happens because your users suspend the app and open it later again. In the meantime, Android stops the app process if it needs the resources. This means that all data in memory and singletons will be destroyed.
When yor users resume the app, the last opened activity will be opened. If that's the GameActivity, you will run in this error.
You can test the behaviour by adjusting the background process limit in the Android developer settings. In a device or emulator, go to the developer settings. Set "Background process limit" to "no background processes". Open your app, go to the GameActivity and then open another app. Wait a few seconds. Open your app again. It should now crash. If it doesn't work, try opening a few more apps and wait a little longer so Android actually stops your app in the background.