Является ли LiveData нулевым в Kotlin? Почему Android Studio может его скомпилировать? - PullRequest
2 голосов
/ 26 мая 2020

На мой взгляд, Kotlin является нулевым.

Код A взят из проекта Universal Android Musi c Player Sample, вы можете увидеть здесь

Кажется, что val rootMediaId: LiveData<String> не является нулевым безопасным в коде A, нулевая строка может быть присвоена rootMediaId, я не знаю, почему Android Studio может скомпилировать этот код, вы можете мне сказать?

Я считаю, что код B является авторитетным кодом.

Код A

viewModel.rootMediaId.observe(this,
                Observer<String> { rootMediaId ->
                    if (rootMediaId != null) {
                        navigateToMediaItem(rootMediaId)
                    }
                })



class MainActivityViewModel(
    private val musicServiceConnection: MusicServiceConnection
) : ViewModel() {

    val rootMediaId: LiveData<String> =
        Transformations.map(musicServiceConnection.isConnected) { isConnected ->
            if (isConnected) {
                musicServiceConnection.rootMediaId
            } else {
                null
            }
        }
   ...
}

Код B

class MainActivityViewModel(
    private val musicServiceConnection: MusicServiceConnection
) : ViewModel() {

    val rootMediaId: LiveData<String?> =
        Transformations.map(musicServiceConnection.isConnected) { isConnected ->
            if (isConnected) {
                musicServiceConnection.rootMediaId
            } else {
                null
            }
        }
   ...
}

Ответы [ 2 ]

4 голосов
/ 26 мая 2020

Это потому, что Live Data записывается в Java, поэтому Kotlin здесь использует тип платформы. Подробнее об этом можно прочитать здесь . В двух словах: Java типы не содержат информации о допустимости значений NULL, поэтому Колин не может определить правильный тип. String из Java может быть String или String? в Kotlin. Android студия отмечает такие String типы как String!, чтобы вы могли обратить внимание и самостоятельно установить соответствующий тип.

1 голос
/ 26 мая 2020

Ответ Андрея Танана описывает общую ситуацию. Но специально для LiveData обратите внимание, что getValue() (или value в Kotlin) допускает значение NULL, поэтому набирается как T? в Kotlin. Так что в некотором смысле не имеет значения, набран результат как LiveData<String> или LiveData<String?>; значения, которые вы получаете от него, равны String? в любом случае.

В этом вопросе также указано, что Observer принимает T?, но это, похоже, не отражено в документации .

...