kotlin Singleton尚未在某些设备上初始化

dojqjjoe  于 2023-03-30  发布在  Kotlin
关注(0)|答案(1)|浏览(101)

该应用程序使用单例GameStorage为用户保存一些设置。它在模拟器和我自己的设备上运行良好,但从Google Play我得到了几个崩溃报告lateinit property prefs has not been initialized
从Android 8.0到13.0一共有四份报告。
当应用启动时,在MainActivity中初始化单例

GameStorage.shared.init(applicationContext)

然后调用GameActivity中的方法:

if (GameStorage.shared.isSoundOn) {
    // ...
}

单例:

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)
        }

    // ...
}
y4ekin9u

y4ekin9u1#

发生这种情况是因为您的用户暂停应用程序并稍后再次打开它。与此同时,Android会在需要资源时停止应用程序进程。这意味着内存和单例中的所有数据都将被销毁。
当你的用户恢复应用时,最后打开的Activity将被打开。如果那是GameActivity,你将在此错误中运行。
您可以通过调整Android开发者设置中的后台进程限制来测试该行为。在设备或模拟器中,转到开发者设置。将“后台进程限制”设置为“无后台进程”。打开您的应用,转到GameActivity,然后打开另一个应用。等待几秒钟。再次打开您的应用。它现在应该崩溃。如果它不工作,尝试多打开几个应用程序,再等一段时间,这样Android实际上会在后台停止你的应用程序。

相关问题