A
A
artem2021-08-30 13:08:57
Android
artem, 2021-08-30 13:08:57

Why does the application crash because of the sharedPreferences change handler?

There is an Activity -> there are 3 fragments in it -> in one of the fragments I call DialogFragment

// Вызываю класс диалога
        binding.editUserProfile.setOnClickListener {
            dialogEditUser.show(childFragmentManager, "DialogUserEdit")
        }


You can set some values ​​in the dialog, after that you can save them, and thus close the dialog.
When they are saved, the Data is Saved in SharedPreferences, and on SharedPreferences I hung a data change handler. When the data changes, I write it to LiveData.
When the dialog is opened, the value input fields are set to the default data taken from LiveData, and they, in turn, are set from SharedPreferences

The class in which LIveData interacts with SharedPreferenceHelper.
SharedPreferenceHelper - a class that I created to work with SharedPreference
class ViewModelUser(application: Application) : AndroidViewModel(application),
    SharedPreferences.OnSharedPreferenceChangeListener {

    val sharedPreferencesHelper: SharedPreferencesHelper by lazy {
        SharedPreferencesHelper(getApplication())
    }

    val liveDataName: MutableLiveData<String> by lazy {
        MutableLiveData<String>()
    }

    val liveDataWeight: MutableLiveData<Float> by lazy {
        MutableLiveData<Float>()
    }

    init {
        liveDataName.value = sharedPreferencesHelper.getUserName()
        liveDataWeight.value = sharedPreferencesHelper.getUserWeight()

//        sharedPreferencesHelper.preferenceUser.registerOnSharedPreferenceChangeListener(this)
    }



    // set data from dialogUserEdit to LiveData
    override fun onSharedPreferenceChanged(preferences: SharedPreferences?, key: String?) {
        when(key) {
            SharedPreferencesHelper.KEY_NAME_USER ->
                liveDataName.value = sharedPreferencesHelper.getUserName()

            SharedPreferencesHelper.KEY_WEIGHT_USER ->
                liveDataWeight.value = sharedPreferencesHelper.getUserWeight()
        }
    }

    override fun onCleared() {

        sharedPreferencesHelper.preferenceUser.unregisterOnSharedPreferenceChangeListener(this)

        super.onCleared()
    }
    
}


Dialog Methods That Participate in Value Processing
// save data in dialog
        bindingDialog.saveEditsButton.setOnClickListener {

            val userWeight = bindingDialog.weightEditSlider.value
            val userName = bindingDialog.nameEditInput.editText?.text.toString()

            // просто запись в sharedPreferences через класс live Data
            liveDataUser.sharedPreferencesHelper.setUserWeight(userWeight) 
            liveDataUser.sharedPreferencesHelper.setUserName(userName)

            dismiss()
        }

// Беру начальные значения из LiveData, которые взяли значения из sharedPrefrences
           liveDataUser.liveDataName.observe(requireActivity()) {
                bindingDialog.nameEditInput.editText?.setText(it)
            }

            liveDataUser.liveDataWeight.observe(requireActivity()) {
                bindingDialog.finalWeight.text = "${getString(R.string.weight)} $it"
                bindingDialog.weightEditSlider.value = it
            }


What is the problem? When I open this dialog and write data to it, everything is fine, but when I then switch between fragments and reopen the dialog, after which I write the data, the application crashes and gives an error


Fragment DialogEditUser {b2c1485} (8e13f608-14d6-49dd- 81e4-6265f421b654) not attached to a context.

612caca8c3024864016996.jpeg

I tried removing the change handler

// set data from dialogUserEdit to LiveData
    override fun onSharedPreferenceChanged(preferences: SharedPreferences?, key: String?) {
        when(key) {
            SharedPreferencesHelper.KEY_NAME_USER ->
                liveDataName.value = sharedPreferencesHelper.getUserName()

            SharedPreferencesHelper.KEY_WEIGHT_USER ->
                liveDataWeight.value = sharedPreferencesHelper.getUserWeight()
        }
    }


And everything works, but the relevance of displaying the data is not correct. The data is displayed only when re-accessing sharedPreferences, for me it is restarting the application.

I tried to write everything as clearly as possible. Thanks to everyone who helped in some way

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question