如何将 LiveData 保存到 saveStateHandle 中?

How to save LiveData into saveStateHandle?

如所示,我们可以将LiveData保存在savedStateHandle中。

我可以轻松做到

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

我哪里弄错了?

查看代码后,意识到我只需要保存值,就像@Parth 在上面的评论中提到的那样。

savedStateHandle.set(KEY, textLiveData.value)

说明

如果我们查看 SavedStateHandle.javaset

@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);
    }
}

这说明如果有的话,它会把数据放到我们存入mLiveDatasmutableLiveData中。

为了确保我们的liveData在mLiveDatas,我们只需要在开始时使用textLiveData = savedStateHandle.getLiveData(KEY)。检查 getLiveDataSavedStateHandle.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,如果还没有。

显然更好的答案是,我们甚至不需要

savedStateHandle.set(KEY, textLiveData.value)

虽然这是允许的,但当我们设置

textLiveData.value = "Some data"

这已经保存到状态。由于 textLiveData 是从 savedStateHandle 中检索到的,如下所示。

textLiveData = savedStateHandle.getLiveData(KEY) 

因此 textLiveData 已经存储在 savedStateHandle 中,对 textLiveData.value 的更改无意中保存在 savedStateHandle 中。

您可以使用 val textLiveData: MutableLiveData<String> = savedStateHandle.getLiveData(KEY) 构造一个 MutableLiveData 并自动保存到 savedInstanceState

savedStateHandle.set(KEY, textLiveData)

你不需要这样做,因为 getLiveData 是一个 SavingStateLiveData,它会自动处理这个。

那是因为你的你class不接受。 您可以输入 ParcelableSerializable 类型。

这是ACCEPTABLE_CLASSES

的列表
private static final Class[] ACCEPTABLE_CLASSES = new Class[]{
        //baseBundle
        boolean.class,
        boolean[].class,
        double.class,
        double[].class,
        int.class,
        int[].class,
        long.class,
        long[].class,
        String.class,
        String[].class,
        //bundle
        Binder.class,
        Bundle.class,
        byte.class,
        byte[].class,
        char.class,
        char[].class,
        CharSequence.class,
        CharSequence[].class,
        // type erasure ¯\_(ツ)_/¯, we won't eagerly check elements contents
        ArrayList.class,
        float.class,
        float[].class,
        Parcelable.class,
        Parcelable[].class,
        Serializable.class,
        short.class,
        short[].class,
        SparseArray.class,
        (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? Size.class : int.class),
        (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? SizeF.class : int.class),
};