Я видел много примеров кодов в Java с пользовательским SavedState, используя простой шаблон
override protected Parcelable onSaveInstanceState() {
final Parcelable superState = super.onSaveInstanceState();
final SavedState mySavedState = new SavedState(superState)
...
return mySavedState;
}
Все выглядит красиво и компилируется в Java, и МОЖНО работает нормально. SavedState
конструктор вызывает BaseSavedState(Parcelable superState)
конструктор, который вызывает protected AbsSavedState(Parcelable superState)
конструктор.
Проблема заключается в том, что вы конвертируете это в Kotlin и начинаете принудительно обнулять. Вы быстро обнаружите, что View.onSaveInstanceState()
- это Nullable
, но конструктор AbsSavedState(Parcelable superState)
проверяет суперсостояние на наличие нуля и создает исключение, если оно null
.
Большую часть времени View.onSaveInstanceState()
на самом деле not-null
так что вы не нажмете исключение нулевого указателя. Но контракт понятен - он может быть нулевым. В этом случае у вас есть Cra sh.
В Kotlin, с другой стороны, у вас есть ошибка времени компиляции, которая не легко решаема, потому что что здесь делать правильно? Вы могли бы подумать, что вы просто соединяете две стороны водопровода, но с одной стороны есть выход nullable
, а с другой стороны non-nullable Parcelable
input.
Ирония в том, что AbsSavedState
имеет также собственный конструктор, назначающий null
в супер-состояние, чтобы он мог работать с обнуляемым супер-типом, но в любом случае есть эта нулевая проверка.
Это выглядит как неумышленное несоответствие для меня. Я ожидал бы, что эти состояния будут совместимы с обеих сторон, и в Java никто действительно не заботился о том, чтобы проверить исходный код, действительно ли он принимает обнуляемые типы, предполагая, что все в порядке. И это работало хорошо для большинства, пока какая-то странная реализация не вернула null
.
Но что должно быть правильным способом здесь. Это действительно ошибка или смещение в исходном коде? Может кто-нибудь пролить свет на это?