Как добавить исключение в пользовательский геттер Kotlin и остановить запуск приложения? - PullRequest
0 голосов
/ 14 декабря 2018

Я хочу убедиться, что мой MediatorLiveData имеет фактическое установленное значение:

val entries = MediatorLiveData<List<Entry>>()
    get() = when {
        entries.value == null -> throw IllegalStateException("wah")
        else -> field
    }

Я не получаю ошибок компилятора, но при выполнении кода я получаю StackOverflow, потому что метод получения вызывается снова и сновав пути (entries.value == null).

1.Как создать исключение в пользовательском геттере и остановить запуск приложения


ОБНОВЛЕНИЕ С ЗАКЛЮЧИТЕЛЬНЫМ РЕШЕНИЕМ: Спасибо @zapl и @kcoppock за ваши ответы.Они оба помогли мне найти окончательное решение:

private lateinit var _entries: LiveData<List<Entry>>
val entries = MediatorLiveData<List<Entry>>()
    get() = when {
        !::_entries.isInitialized -> throw IllegalStateException("EntryListViewModel was not initialized. Please call init() first.")
        else -> field
    }

fun init() {
    _entries = getEntries(false)
    entries.addSource(_entries) { entries.value = it.orEmpty() }
}

fun refreshEntries() {
    entries.removeSource(_entries)
    _entries = getEntries(true)
    entries.addSource(_entries) { entries.value = it.orEmpty() }
}

Я также узнал из другого источника о .isInitialized для lateinit vars, который можно использовать именно для того, что мне нужно.Также хорошей идеей было изящное отступление к пустому списку.

1 Ответ

0 голосов
/ 14 декабря 2018

Что бы я сделал, это оставил LiveData закрытым и выделил отдельный метод доступа для отмеченного свойства:

private val _entries = MediatorLiveData<List<Entry>>()
val entries: List<Entry>
    get() = _entries.value!!

Еще лучше, если вы явно не хотите, чтобы аварийно завершился в этомВ этом случае вы могли бы просто вернуть пустой список:

private val _entries = MediatorLiveData<List<Entry>>()
val entries: List<Entry>
    get() = _entries.value.orEmpty()

Тем не менее, смысл LiveData заключается в использовании наблюдателя, поэтому вы получите обновление только после публикации значения.

РЕДАКТИРОВАТЬ: Если ваша цель состоит в том, чтобы принудительно установить начальное значение, вы можете создать подкласс, который обеспечивает это:

class NonNullMediatorLiveData<T>(initialValue: T) : MediatorLiveData<T>() {
    init { value = initialValue }

    override fun getValue(): T = super.getValue()!!

    override fun setValue(value: T) {
        // assert since the parent is defined in Java
        super.setValue(value!!)
    }
}
...