Как сохранить LiveData в saveStateHandle? - PullRequest
0 голосов
/ 12 апреля 2020

Как показано в { ссылка }, мы можем сохранить LiveData в saveStateHandle.

Я мог бы легко это сделать { ссылка }

private val textLiveData: MutableLiveData<String>

init {
    textLiveData = savedStateHandle.getLiveData(KEY)
}

Однако, при попытке сохранить его, как показано ниже,

savedStateHandle.set(KEY, textLiveData)

Я получил ошибку

java.lang.IllegalArgumentException: Can't put value with type class androidx.lifecycle.SavedStateHandle$SavingStateLiveData into saved state

Где я ошибся?

Ответы [ 3 ]

1 голос
/ 12 апреля 2020

Видимо, лучший ответ: нам даже не нужно

savedStateHandle.set(KEY, textLiveData.value)

Хотя это допустимо, когда мы устанавливаем

textLiveData.value = "Some data"

Это уже сохранено в состоянии , Поскольку textLiveData извлекается из savedStateHandle, как показано ниже.

textLiveData = savedStateHandle.getLiveData(KEY) 

Следовательно, textLiveData уже хранится в savedStateHandle, а изменения в textLiveData.value непреднамеренно сохраняются в savedStateHandle .

0 голосов
/ 17 апреля 2020

Вы можете использовать val textLiveData: MutableLiveData<String> = savedStateHandle.getLiveData(KEY), который создает MutableLiveData, который автоматически сохраняется в savedInstanceState.

saveStateHandle.set (KEY, textLiveData)

Вам не нужно этого делать, потому что getLiveData - это SavingStateLiveData, который автоматически обрабатывает это.

0 голосов
/ 12 апреля 2020

Изучив код, поймите, что мне просто нужно сохранить значение, как то, что @Parth упомянул в комментарии выше.

savedStateHandle.set(KEY, textLiveData.value)

Объяснение

Если мы посмотрим на set из SavedStateHandle.java

@MainThread
public <T> void set(@NonNull String key, @Nullable T value) {
    validateValue(value);
    @SuppressWarnings("unchecked")
    MutableLiveData<T> mutableLiveData = (MutableLiveData<T>) mLiveDatas.get(key);
    if (mutableLiveData != null) {
        // it will set value;
        mutableLiveData.setValue(value);
    } else {
        mRegular.put(key, value);
    }
}

Это показывает, что данные будут помещены в mutableLiveData, который мы храним в mLiveDatas, если таковой имеется.

Чтобы наши liveData были в mLiveDatas, нам просто нужно использовать textLiveData = savedStateHandle.getLiveData(KEY) в начале. Извлеките getLiveData из SavedStateHandle.java

@NonNull
private <T> MutableLiveData<T> getLiveDataInternal(
        @NonNull String key,
        boolean hasInitialValue,
        @Nullable T initialValue) {
    MutableLiveData<T> liveData = (MutableLiveData<T>) mLiveDatas.get(key);
    if (liveData != null) {
        return liveData;
    }
    SavingStateLiveData<T> mutableLd;
    // double hashing but null is valid value
    if (mRegular.containsKey(key)) {
        mutableLd = new SavingStateLiveData<>(this, key, (T) mRegular.get(key));
    } else if (hasInitialValue) {
        mutableLd = new SavingStateLiveData<>(this, key, initialValue);
    } else {
        mutableLd = new SavingStateLiveData<>(this, key);
    }
    mLiveDatas.put(key, mutableLd);
    return mutableLd;
}

Он создаст его и поместит в mLiveDatas, когда мы запросим его, если его еще нет.

...