Это действительно недостаток в C ++ 11, как объяснили другие, в C ++ 11 статическая переменная-член constexpr, в отличие от любой другой глобальной переменной constexpr, имеет внешнюю связь, поэтому она должна быть явно определена где-то.
Также стоит отметить, что вы часто можете избежать со статическими переменными-членами constexpr без определений при компиляции с оптимизацией, так как они могут оказаться вложенными во все виды использования, но если вы легко компилируете без оптимизации, ваша программа не будет связываться. Это делает эту очень распространенную скрытую ловушку - ваша программа отлично компилируется с оптимизацией, но как только вы отключите оптимизацию (возможно, для отладки), она не может связываться.
Хорошая новость: этот недостаток исправлен в C ++ 17! Этот подход немного запутан, хотя: в C ++ 17 статические константные переменные-члены-константы неявно встроены . Наличие inline, применяемого к переменным , является новой концепцией в C ++ 17, но это фактически означает, что в любом месте они не нуждаются в явном определении.
Вам нужно использовать SingleLiveEvent для этого случая.
class SingleLiveEvent<T> : MutableLiveData<T>() {
private val pending = AtomicBoolean(false)
@MainThread
override fun observe(owner: LifecycleOwner, observer: Observer<T>) {
if (hasActiveObservers()) {
Log.w(TAG, "Multiple observers registered but only one will be notified of changes.")
}
// Observe the internal MutableLiveData
super.observe(owner, Observer<T> { t ->
if (pending.compareAndSet(true, false)) {
observer.onChanged(t)
}
})
}
@MainThread
override fun setValue(t: T?) {
pending.set(true)
super.setValue(t)
}
/**
* Used for cases where T is Void, to make calls cleaner.
*/
@MainThread
fun call() {
value = null
}
companion object {
private const val TAG = "SingleLiveEvent"
}
}
А внутри класса viewmodel создать объект, подобный:
val snackbarMessage = SingleLiveEvent<Int>()
Если вам нужно простое решение, попробуйте следующее:
class SingleLiveData<T> : MutableLiveData<T?>() {
override fun observe(owner: LifecycleOwner, observer: Observer<in T?>) {
super.observe(owner, Observer { t ->
if (t != null) {
observer.onChanged(t)
postValue(null)
}
})
}
}
Используйте его как обычные MutableLiveData