RuntimeException:首选项尚未初始化
RuntimeException: preferences has not been initialised
我搜索了很多类似的 SharedPreferences 问题,但无法应用于我的项目。
这是一个 RuntimeException,需要初始化 SharedPreferences lateinit 变量。
错误信息:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.me.tabuild3/com.me.tabuild3.Tutorial}: kotlin.UninitializedPropertyAccessException: lateinit property mPref has not been initialized
(...)
Caused by: kotlin.UninitializedPropertyAccessException: lateinit property mPreferences has not been initialized
at com.me.tabuild3.Z3Preferences.<init>(Z3Preferences.kt:15)
at com.me.tabuild3.Tutorial.onCreate(Tutorial.kt:15)
这是Tutorial.kt,它触发了错误:
class Tutorial : AppCompatActivity() {
val binding by lazy {
B00TutorialBinding.inflate(layoutInflater)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.b00_tutorial)
val fragmentList = listOf(Z0A(), Z1B(), Z3Preferences()) // the 15th line is here
val adapter = Z99FragmentAdapter(this)
adapter.fragmentList = fragmentList
binding.tutorialPager.adapter = adapter
binding.tutorialPager.currentItem = 1
}
}
这个activity加载了三个片段,第三个,Z3Preferences(),编辑SharedPreferences来修改东西(至少我是这么打算的)。
这是 Z3Preferences,其中包含实际(?)错误:
class Z3Preferences : Fragment() {
lateinit var binding: F04PrefBinding
private lateinit var mPref: SharedPreferences // seems this thing has to be initialised
val preferencesEditor: SharedPreferences.Editor = mPref.edit() // same error message for this line when the upper solved(?)
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
binding = F04PrefBinding.inflate(inflater, container, false)
return binding.root
}
override fun onResume() {
super.onResume()
binding.radioGroupTextSize.setOnCheckedChangeListener { group, checkedId ->
when (checkedId) {
R.id.textSize_RB1 -> preferencesEditor.putInt("TXTSZ", 12)
R.id.textSize_RB2 -> preferencesEditor.putInt("TXTSZ", 14)
R.id.textSize_RB3 -> preferencesEditor.putInt("TXTSZ", 16)
R.id.textSize_RB4 -> preferencesEditor.putInt("TXTSZ", 18)
R.id.textSize_RB5 -> preferencesEditor.putInt("TXTSZ", 20)
}
}
binding.radioGroupTextSpeed.setOnCheckedChangeListener { group, checkedId ->
when (checkedId) {
R.id.textSpd_RB1 -> {
preferencesEditor.putInt("TXTSP", 160)
preferencesEditor.putBoolean("TXTAN", true)
}
R.id.textSpd_RB2 -> {
preferencesEditor.putInt("TXTSP", 120)
preferencesEditor.putBoolean("TXTAN", true)
}
R.id.textSpd_RB3 -> {
preferencesEditor.putInt("TXTSP", 80)
preferencesEditor.putBoolean("TXTAN", true)
}
R.id.textSpd_RB4 -> {
preferencesEditor.putInt("TXTSP", 40)
preferencesEditor.putBoolean("TXTAN", true)
}
R.id.textSpd_RB5 -> {
preferencesEditor.putInt("TXTSP", 40)
preferencesEditor.putBoolean("TXTAN", false)
}
}
}
}
override fun onPause() {
super.onPause()
preferencesEditor.apply()
}
}
所以..我该如何初始化 lateinit var mPref?在这一点上我完全迷路了,类似的问题有不同的应用程序构造,我无法理解。
您需要上下文来初始化 sharedPreferences。
你可以这样做:
mPref = this.activity!!.getSharedPreferences("pref", Context.MODE_PRIVATE)
我会在片段的 onCreate 方法中执行此操作。
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mPref = this.activity!!.getSharedPreferences("pref",Context.MODE_PRIVATE)
//other initializations ...
}
So.. How do I initialise the lateinit var mPref?
您将其设置为某个有效值,通常尽早设置。在 Android 上,这通常意味着在 onCreate
或 onCreateView
上这样做。但至少在任何尝试访问它之前。您可以在 onCreateView
:
中执行此操作
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
mPref = // get preferences in your prefered way
binding = F04PrefBinding.inflate(inflater, container, false)
return binding.root
}
it shoots the same error for the next line(I marked on the code in the post): "lateinit property mPref has not been initialized", but at the next line! How do I do this?
您试图在声明后立即使用未初始化的 lateinit
变量:
private lateinit var mPref: SharedPreferences // Declared but not initialized
val preferencesEditor: SharedPreferences.Editor = mPref.edit() // Immediately attemps to use mPref which is not initialized (during constructor call)
你不需要像那样立即初始化编辑器。
您可以将其设置为 属性,因此它仅在访问时尝试访问 mPref,而在构造函数调用期间 不尝试 ,这假定它是有效的您尝试访问编辑器的时间:
val preferencesEditor: SharedPreferences.Editor get() = mPref.edit()
或者,您可以将编辑器本身设为 lateinit
属性 并稍后对其进行初始化:
lateinit var preferencesEditor: SharedPreferences.Editor
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
mPref = // get preferences in your prefered way
preferencesEditor = mPref.edit()
binding = F04PrefBinding.inflate(inflater, container, false)
return binding.root
}
请查看文档以了解 lateinit and kotlin constructors 的工作原理。
我搜索了很多类似的 SharedPreferences 问题,但无法应用于我的项目。 这是一个 RuntimeException,需要初始化 SharedPreferences lateinit 变量。
错误信息:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.me.tabuild3/com.me.tabuild3.Tutorial}: kotlin.UninitializedPropertyAccessException: lateinit property mPref has not been initialized
(...)
Caused by: kotlin.UninitializedPropertyAccessException: lateinit property mPreferences has not been initialized
at com.me.tabuild3.Z3Preferences.<init>(Z3Preferences.kt:15)
at com.me.tabuild3.Tutorial.onCreate(Tutorial.kt:15)
这是Tutorial.kt,它触发了错误:
class Tutorial : AppCompatActivity() {
val binding by lazy {
B00TutorialBinding.inflate(layoutInflater)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.b00_tutorial)
val fragmentList = listOf(Z0A(), Z1B(), Z3Preferences()) // the 15th line is here
val adapter = Z99FragmentAdapter(this)
adapter.fragmentList = fragmentList
binding.tutorialPager.adapter = adapter
binding.tutorialPager.currentItem = 1
}
}
这个activity加载了三个片段,第三个,Z3Preferences(),编辑SharedPreferences来修改东西(至少我是这么打算的)。
这是 Z3Preferences,其中包含实际(?)错误:
class Z3Preferences : Fragment() {
lateinit var binding: F04PrefBinding
private lateinit var mPref: SharedPreferences // seems this thing has to be initialised
val preferencesEditor: SharedPreferences.Editor = mPref.edit() // same error message for this line when the upper solved(?)
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
binding = F04PrefBinding.inflate(inflater, container, false)
return binding.root
}
override fun onResume() {
super.onResume()
binding.radioGroupTextSize.setOnCheckedChangeListener { group, checkedId ->
when (checkedId) {
R.id.textSize_RB1 -> preferencesEditor.putInt("TXTSZ", 12)
R.id.textSize_RB2 -> preferencesEditor.putInt("TXTSZ", 14)
R.id.textSize_RB3 -> preferencesEditor.putInt("TXTSZ", 16)
R.id.textSize_RB4 -> preferencesEditor.putInt("TXTSZ", 18)
R.id.textSize_RB5 -> preferencesEditor.putInt("TXTSZ", 20)
}
}
binding.radioGroupTextSpeed.setOnCheckedChangeListener { group, checkedId ->
when (checkedId) {
R.id.textSpd_RB1 -> {
preferencesEditor.putInt("TXTSP", 160)
preferencesEditor.putBoolean("TXTAN", true)
}
R.id.textSpd_RB2 -> {
preferencesEditor.putInt("TXTSP", 120)
preferencesEditor.putBoolean("TXTAN", true)
}
R.id.textSpd_RB3 -> {
preferencesEditor.putInt("TXTSP", 80)
preferencesEditor.putBoolean("TXTAN", true)
}
R.id.textSpd_RB4 -> {
preferencesEditor.putInt("TXTSP", 40)
preferencesEditor.putBoolean("TXTAN", true)
}
R.id.textSpd_RB5 -> {
preferencesEditor.putInt("TXTSP", 40)
preferencesEditor.putBoolean("TXTAN", false)
}
}
}
}
override fun onPause() {
super.onPause()
preferencesEditor.apply()
}
}
所以..我该如何初始化 lateinit var mPref?在这一点上我完全迷路了,类似的问题有不同的应用程序构造,我无法理解。
您需要上下文来初始化 sharedPreferences。 你可以这样做:
mPref = this.activity!!.getSharedPreferences("pref", Context.MODE_PRIVATE)
我会在片段的 onCreate 方法中执行此操作。
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mPref = this.activity!!.getSharedPreferences("pref",Context.MODE_PRIVATE)
//other initializations ...
}
So.. How do I initialise the lateinit var mPref?
您将其设置为某个有效值,通常尽早设置。在 Android 上,这通常意味着在 onCreate
或 onCreateView
上这样做。但至少在任何尝试访问它之前。您可以在 onCreateView
:
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
mPref = // get preferences in your prefered way
binding = F04PrefBinding.inflate(inflater, container, false)
return binding.root
}
it shoots the same error for the next line(I marked on the code in the post): "lateinit property mPref has not been initialized", but at the next line! How do I do this?
您试图在声明后立即使用未初始化的 lateinit
变量:
private lateinit var mPref: SharedPreferences // Declared but not initialized
val preferencesEditor: SharedPreferences.Editor = mPref.edit() // Immediately attemps to use mPref which is not initialized (during constructor call)
你不需要像那样立即初始化编辑器。
您可以将其设置为 属性,因此它仅在访问时尝试访问 mPref,而在构造函数调用期间 不尝试 ,这假定它是有效的您尝试访问编辑器的时间:
val preferencesEditor: SharedPreferences.Editor get() = mPref.edit()
或者,您可以将编辑器本身设为 lateinit
属性 并稍后对其进行初始化:
lateinit var preferencesEditor: SharedPreferences.Editor
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
mPref = // get preferences in your prefered way
preferencesEditor = mPref.edit()
binding = F04PrefBinding.inflate(inflater, container, false)
return binding.root
}
请查看文档以了解 lateinit and kotlin constructors 的工作原理。