Android studio lateinit属性ApplicationContext尚未初始化

Android studio lateinit属性ApplicationContext尚未初始化,android-studio,kotlin,Android Studio,Kotlin,您好,我对编程行业还比较陌生,我的项目有问题。 我有一个简单的计数器,可以计算你看到多少只鸟,然后根据你按下的按钮改变文本视图(显示计数器)的颜色。 我正在使用viewModel和实时数据以及数据绑定来实现这一点,而且效果很好。现在,当我尝试添加共享首选项来存储我的数据,以便它们能够在应用程序关闭后生存下来时。当我尝试使用“userDataProvider”时,我得到了一个我不知道如何修复的错误 //错误 原因:kotlin.UninitializedPropertyAccessExceptio

您好,我对编程行业还比较陌生,我的项目有问题。 我有一个简单的计数器,可以计算你看到多少只鸟,然后根据你按下的按钮改变文本视图(显示计数器)的颜色。 我正在使用viewModel和实时数据以及数据绑定来实现这一点,而且效果很好。现在,当我尝试添加共享首选项来存储我的数据,以便它们能够在应用程序关闭后生存下来时。当我尝试使用“userDataProvider”时,我得到了一个我不知道如何修复的错误

//错误 原因:kotlin.UninitializedPropertyAccessException:lateinit属性ApplicationContext尚未初始化 在com.example.lv4_birdsconter.birdsconterApp$Companion.getApplicationContext(birdsconterApp.kt:11) 在com.example.lv4_birdsconter.PrefsManager.setCounter上(PrefsManager.kt:53) 在com.example.lv4_birdsconter.PrefsManager.setBirdCounter(PrefsManager.kt:19)上 在com.example.lv4_birdsconter.birdsconter.onCreate上(birdsconter.kt:52)

//鸟计数器

package com.example.lv4_birdscounter

import android.graphics.Color
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import com.example.lv4_birdscounter.databinding.ActivityMainBinding


class BirdsCounter : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding

    lateinit var viewModel: BirdsCounterViewModel

    private val userDataProvider: UserDataProvider by lazy { PrefsManager }

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



        viewModel = ViewModelProvider(this).get(BirdsCounterViewModel::class.java)


        binding = DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main).apply {
            this.setLifecycleOwner(this@BirdsCounter)
            this.viewmodel=viewModel
        }


        viewModel.birdsSeen.observe(this, Observer {
            //display new data
            binding.tvCounter.text = it.toString()
        })

        viewModel.birdsColor.observe(this, Observer {
            //display new data
            binding.tvCounter.setBackgroundColor(Color.parseColor(it))

            //Make number more visible by changing the colour of the text
            when(it){
                viewModel.GREEN -> binding.tvCounter.setTextColor(Color.BLACK)
                viewModel.WHITE -> binding.tvCounter.setTextColor(Color.BLACK)
                else -> binding.tvCounter.setTextColor(Color.WHITE)
            }
        })

        //Crashes
        userDataProvider.birdCounter = 5

        setContentView(binding.root)
    }

}
//PrefsManager.kt

    package com.example.lv4_birdscounter

import android.content.Context

interface UserDataProvider{
    var birdCounter: Int
    var tvColor: String
}


object PrefsManager: UserDataProvider{

    private val PREFS_FILE = "preferences"
    private val COUNTER_ID = "counter_id"
    private val COLOR_ID = "color_id"

    override var birdCounter: Int
        get() = getCounter()
        set(value) = setCounter(value)

    override var tvColor: String
        get() = getColor()
        set(value) = setColor(value)


    //for color
    private fun getColor(): String {
        return BirdsCounterApp.ApplicationContext.getSharedPreferences(
                PREFS_FILE,
                Context.MODE_PRIVATE
        ).getString(COLOR_ID, "#4A6572")?: "#4A6572"
    }

    private fun setColor(value: String){
        BirdsCounterApp.ApplicationContext.getSharedPreferences(
                PREFS_FILE,
                Context.MODE_PRIVATE)
                .edit()
                .putString(COLOR_ID, value)
                .apply()
    }


    //for counter
    private fun getCounter(): Int {
        return BirdsCounterApp.ApplicationContext.getSharedPreferences(
                PREFS_FILE,
                Context.MODE_PRIVATE
        ).getInt(COUNTER_ID, 0)?:0
    }

    private fun setCounter(value: Int){
        BirdsCounterApp.ApplicationContext.getSharedPreferences(
                PREFS_FILE,
                Context.MODE_PRIVATE)
                .edit() // dobivamo Editor instancu koja se koristi za izmjenu SharedPreferences-a
                .putInt(COUNTER_ID, value)
                .apply() // pohranjujemo promjene
    }
}
//鸟瞰模型

    package com.example.lv4_birdscounter

import android.graphics.Color
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel



class BirdsCounterViewModel() : ViewModel() {


    val RED = "#D82929"
    val BLUE = "#2121E1"
    val WHITE = "#FFFFFFFF"
    val GREEN = "#2DF62D"
    val LIGHT_GRAY = "#4A6572"

    private val _birdsSeen: MutableLiveData<Int> = MutableLiveData<Int>(0)
    val birdsSeen: LiveData<Int> = _birdsSeen

    private val _birdsColor: MutableLiveData<String> = MutableLiveData<String>("#4A6572")
    val birdsColor: LiveData<String> = _birdsColor

    fun onButtonPressed(color: String){
        _birdsSeen.value?.let { _birdsSeen.postValue(it + 1) }
        _birdsColor.value?.let { _birdsColor.postValue(color) }
    }

    fun onResetButtonPressed(){
        _birdsSeen.value?.let { _birdsSeen.postValue(0) }
        _birdsColor.value?.let { _birdsColor.postValue(LIGHT_GRAY) }
    }


}
package com.example.lv4\u鸟计数器
导入android.graphics.Color
导入androidx.lifecycle.LiveData
导入androidx.lifecycle.MutableLiveData
导入androidx.lifecycle.ViewModel
类BirdsCounterViewModel():ViewModel(){
val RED=“#D82929”
val BLUE=“#2121E1”
val WHITE=“#FFFFFFFF”
val GREEN=“#2DF62D”
val浅灰色=“#4A6572”
private val_birdseen:MutableLiveData=MutableLiveData(0)
val birdseen:LiveData=\u birdseen
private val_birdscaolor:MutableLiveData=MutableLiveData(“#4A6572”)
val birdsColor:LiveData=\u birdsColor
按下按钮(颜色:字符串){
_birdseen.value?设{u birdseen.postValue(it+1)}
_birdsColor.value?.let{u birdsColor.postValue(color)}
}
按下重置按钮(){
_birdseen.value?设{u birdseen.postValue(0)}
_birdsColor.value?.let{u birdsColor.postValue(浅灰色)}
}
}
//主活动XML

<?xml version="1.0" encoding="utf-8"?>


<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>
        <variable
            name="viewmodel"
            type="com.example.lv4_birdscounter.BirdsCounterViewModel" />

    </data>
    <androidx.constraintlayout.widget.ConstraintLayout


        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/dark_gray"
        tools:context=".BirdsCounter">

        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guide_vertical_center"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            app:layout_constraintGuide_percent="0.5" />


        <TextView
            android:id="@+id/tvCounter"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"

            android:layout_margin="@dimen/tvMargin"
            android:background="@color/light_gray"
            android:textAlignment="center"
            android:textColor="@color/white"

            android:textSize="@dimen/tvTextSize"
            app:layout_constraintLeft_toLeftOf="parent"

            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            tools:text="@string/tvCounterDefaultValue" />

        <Button
            android:id="@+id/btnRed"
            android:layout_width="0dp"
            android:layout_height="wrap_content"

            android:layout_margin="@dimen/btnMargin"
            android:backgroundTint="@color/red"
            android:text="@string/btnRedText"

            android:textColor="@color/white"
            app:layout_constraintEnd_toStartOf="@id/guide_vertical_center"

            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/tvCounter"
            app:strokeColor="@color/black"

            app:strokeWidth="@dimen/btnStrokeWidth"
            android:onClick="@{()->viewmodel.onButtonPressed(viewmodel.RED)}"/>

        <Button
            android:id="@+id/btnBlue"
            android:layout_width="0dp"
            android:layout_height="wrap_content"

            android:layout_margin="@dimen/btnMargin"
            android:backgroundTint="@color/blue"
            android:text="@string/btnBlueText"

            android:textColor="@color/white"
            app:layout_constraintEnd_toEndOf="parent"

            app:layout_constraintStart_toStartOf="@id/guide_vertical_center"
            app:layout_constraintTop_toBottomOf="@id/tvCounter"
            app:strokeColor="@color/black"

            app:strokeWidth="@dimen/btnStrokeWidth"
            android:onClick="@{()->viewmodel.onButtonPressed(viewmodel.BLUE)}"/>


        <Button
            android:id="@+id/btnWhite"
            android:layout_width="0dp"
            android:layout_height="wrap_content"

            android:layout_margin="@dimen/btnMargin"
            android:backgroundTint="@color/white"
            android:text="@string/btnWhiteText"

            android:textColor="@color/black"
            app:layout_constraintEnd_toStartOf="@id/guide_vertical_center"

            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/btnRed"
            app:strokeColor="@color/black"

            app:strokeWidth="@dimen/btnStrokeWidth"
            android:onClick="@{()->viewmodel.onButtonPressed(viewmodel.WHITE)}"/>


        <Button
            android:id="@+id/btnGreen"
            android:layout_width="0dp"
            android:layout_height="wrap_content"

            android:layout_margin="@dimen/btnMargin"
            android:backgroundTint="@color/green"
            android:text="@string/btnGreenText"

            android:textColor="@color/black"
            app:layout_constraintEnd_toEndOf="parent"

            app:layout_constraintStart_toStartOf="@id/guide_vertical_center"
            app:layout_constraintTop_toBottomOf="@id/btnBlue"
            app:strokeColor="@color/black"

            app:strokeWidth="@dimen/btnStrokeWidth"
            android:onClick="@{()->viewmodel.onButtonPressed(viewmodel.GREEN)}"/>

        <Button
            android:id="@+id/btnReset"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"

            android:backgroundTint="@color/black"
            android:text="@string/btnResetText"

            android:textColor="@color/white"


            app:layout_constraintLeft_toLeftOf="@id/guide_vertical_center"
            app:layout_constraintRight_toRightOf="@id/guide_vertical_center"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintTop_toBottomOf="@id/btnWhite"

            android:onClick="@{()->viewmodel.onResetButtonPressed()}"
            />





    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

您不需要在应用程序类中初始化ApplicationContext。Android将为您提供它。你只需要从你需要的地方访问它。ApplicationContext基本上是一个单例实例,可以通过getApplicationContext()在活动中访问。此上下文与应用程序的生命周期相关联

而不是通过伴随对象访问应用程序上下文。通过构造函数将上下文注入到需要使用的相应文件中,并使用该实例。您还可以使用依赖项注入库(如Dagger)来帮助您注入依赖项

您可以执行类似PrefsManager构造函数(val context:context)的操作
要手动将birds counter活动中的上下文注入PrefsManager,然后使用该上下文保存到SharedReferences

感谢您的回答我没有将BirdsCounterApp添加到清单中….--android:name=“.birdsconterApp”--这行代码就是我所需要的
<?xml version="1.0" encoding="utf-8"?>


<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>
        <variable
            name="viewmodel"
            type="com.example.lv4_birdscounter.BirdsCounterViewModel" />

    </data>
    <androidx.constraintlayout.widget.ConstraintLayout


        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/dark_gray"
        tools:context=".BirdsCounter">

        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guide_vertical_center"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            app:layout_constraintGuide_percent="0.5" />


        <TextView
            android:id="@+id/tvCounter"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"

            android:layout_margin="@dimen/tvMargin"
            android:background="@color/light_gray"
            android:textAlignment="center"
            android:textColor="@color/white"

            android:textSize="@dimen/tvTextSize"
            app:layout_constraintLeft_toLeftOf="parent"

            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            tools:text="@string/tvCounterDefaultValue" />

        <Button
            android:id="@+id/btnRed"
            android:layout_width="0dp"
            android:layout_height="wrap_content"

            android:layout_margin="@dimen/btnMargin"
            android:backgroundTint="@color/red"
            android:text="@string/btnRedText"

            android:textColor="@color/white"
            app:layout_constraintEnd_toStartOf="@id/guide_vertical_center"

            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/tvCounter"
            app:strokeColor="@color/black"

            app:strokeWidth="@dimen/btnStrokeWidth"
            android:onClick="@{()->viewmodel.onButtonPressed(viewmodel.RED)}"/>

        <Button
            android:id="@+id/btnBlue"
            android:layout_width="0dp"
            android:layout_height="wrap_content"

            android:layout_margin="@dimen/btnMargin"
            android:backgroundTint="@color/blue"
            android:text="@string/btnBlueText"

            android:textColor="@color/white"
            app:layout_constraintEnd_toEndOf="parent"

            app:layout_constraintStart_toStartOf="@id/guide_vertical_center"
            app:layout_constraintTop_toBottomOf="@id/tvCounter"
            app:strokeColor="@color/black"

            app:strokeWidth="@dimen/btnStrokeWidth"
            android:onClick="@{()->viewmodel.onButtonPressed(viewmodel.BLUE)}"/>


        <Button
            android:id="@+id/btnWhite"
            android:layout_width="0dp"
            android:layout_height="wrap_content"

            android:layout_margin="@dimen/btnMargin"
            android:backgroundTint="@color/white"
            android:text="@string/btnWhiteText"

            android:textColor="@color/black"
            app:layout_constraintEnd_toStartOf="@id/guide_vertical_center"

            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/btnRed"
            app:strokeColor="@color/black"

            app:strokeWidth="@dimen/btnStrokeWidth"
            android:onClick="@{()->viewmodel.onButtonPressed(viewmodel.WHITE)}"/>


        <Button
            android:id="@+id/btnGreen"
            android:layout_width="0dp"
            android:layout_height="wrap_content"

            android:layout_margin="@dimen/btnMargin"
            android:backgroundTint="@color/green"
            android:text="@string/btnGreenText"

            android:textColor="@color/black"
            app:layout_constraintEnd_toEndOf="parent"

            app:layout_constraintStart_toStartOf="@id/guide_vertical_center"
            app:layout_constraintTop_toBottomOf="@id/btnBlue"
            app:strokeColor="@color/black"

            app:strokeWidth="@dimen/btnStrokeWidth"
            android:onClick="@{()->viewmodel.onButtonPressed(viewmodel.GREEN)}"/>

        <Button
            android:id="@+id/btnReset"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"

            android:backgroundTint="@color/black"
            android:text="@string/btnResetText"

            android:textColor="@color/white"


            app:layout_constraintLeft_toLeftOf="@id/guide_vertical_center"
            app:layout_constraintRight_toRightOf="@id/guide_vertical_center"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintTop_toBottomOf="@id/btnWhite"

            android:onClick="@{()->viewmodel.onResetButtonPressed()}"
            />





    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>