Задать вопрос
arteqrt
@arteqrt
Почти не начинающий програмист

Почему падает приложение из-за обработчика изменений sharedPreferences?

Есть Activity -> в нем 3 фрагмента -> в одном из фрагментов я вызываю DialogFragment
// Вызываю класс диалога
        binding.editUserProfile.setOnClickListener {
            dialogEditUser.show(childFragmentManager, "DialogUserEdit")
        }


В диалоге можно задать некоторые значения, после этого можно их сохранить, и тем самым закрыть диалог.
Когда они сохраняются, то происходит Сохранение Данных в SharedPreferences, а на SharedPreferences я повесил обработчик изменения данных. Когда данные меняются, я записываю их в LiveData.
При открытии диалога в поля ввода значений устанавливаются данные по умолчанию взятые из LiveData, а они в свою очередь из SharedPreferences

Класс, в котором LIveData взаимодействует с SharedPreferenceHelper.
SharedPreferenceHelper - класс, который я создал для работы с 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()
    }
    
}


Методы диалога, которые участвуют в обработке значений
// 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
            }


В чем проблема? Я когда открываю этот диалог и записываю в него данные, то все норм, но когда потом я перехожу между фрагментами, и заново открываю диалог, после чего записываю данные - приложение крашиться и выдает ошибку


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

612caca8c3024864016996.jpeg

Я попробовал убрать обработчик изменений

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


И все работает, но актуальность отображения данных не правильная. Данные отображаются только при повторном обращении к sharedPreferences, у меня это перезапуск приложения.

Старался все написать, как можно понятней. Благодарю всех, кто как то помог в решении
  • Вопрос задан
  • 111 просмотров
Подписаться 1 Простой 2 комментария
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы