如何为 MutableLiveData 对象初始化集合值?
How do I initialize a collection value for a MutableLiveData object?
class Foo : ViewModel() {
val bars: MutableLiveData<ArrayList<Bar>> = MutableLiveData()
get() {
if(field.value == null) {
field.setValue(ArrayList()) // NullPointerException
}
}
}
class FooTest(){
@Test fun itShouldNotBlowUp() {
Foo() //nullPointerException
}
}
我不明白如何初始化 MutableLiveData 对象的值。我试图通过 getter 和 init
块延迟初始化它。两种方法在设置值时都会抛出一个空指针。 bars
但是不为空。
这是堆栈跟踪:
java.lang.NullPointerException
at android.arch.core.executor.DefaultTaskExecutor.isMainThread(DefaultTaskExecutor.java:58)
at android.arch.core.executor.ArchTaskExecutor.isMainThread(ArchTaskExecutor.java:116)
at android.arch.lifecycle.LiveData.assertMainThread(LiveData.java:434)
at android.arch.lifecycle.LiveData.setValue(LiveData.java:279)
at android.arch.lifecycle.MutableLiveData.setValue(MutableLiveData.java:33)
at org.Foo.<init>(Foo.kt:10)
at org.FooTest.ShouldNotBlowUp(FooTest.kt:3)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
如何初始化 ArrayList 并将其设置为 bars
的值?
可能是因为您正试图 运行 在测试中这样做。您的示例在 DefaultTaskExecutor.isMainThread() 中失败,看起来像这样:
public boolean isMainThread() {
return Looper.getMainLooper().getThread() == Thread.currentThread();
}
所以Looper.getMainLooper()returns在测试环境下为null
此外,您是否尝试通过 'lazy' 委托初始化 属性?
val bars: MutableLiveData<List<Bar>> by lazy {
MutableLiveData<List<Bar>>().apply {
value = emptyList()
}
}
这对我来说效果很好,而且感觉更地道
问题的答案是:如果你明明想给它一个空值,但是变量不为空,你至少可以在不破坏程序的情况下使用它。
创建一个变量:
val myVariable = MutableLiveData<ArrayList<String>>()
好吧,现在你只需要在类型括号内传递空列表的构造函数,这样你的变量就不会保持空值。
val myVariable = MutableLiveData<ArrayList<String>>(arrayListOf())
我知道这是一个老问题,但如果它可以帮助某人,它帮助我发现了这一点;)
class Foo : ViewModel() {
val bars: MutableLiveData<ArrayList<Bar>> = MutableLiveData()
get() {
if(field.value == null) {
field.setValue(ArrayList()) // NullPointerException
}
}
}
class FooTest(){
@Test fun itShouldNotBlowUp() {
Foo() //nullPointerException
}
}
我不明白如何初始化 MutableLiveData 对象的值。我试图通过 getter 和 init
块延迟初始化它。两种方法在设置值时都会抛出一个空指针。 bars
但是不为空。
这是堆栈跟踪:
java.lang.NullPointerException
at android.arch.core.executor.DefaultTaskExecutor.isMainThread(DefaultTaskExecutor.java:58)
at android.arch.core.executor.ArchTaskExecutor.isMainThread(ArchTaskExecutor.java:116)
at android.arch.lifecycle.LiveData.assertMainThread(LiveData.java:434)
at android.arch.lifecycle.LiveData.setValue(LiveData.java:279)
at android.arch.lifecycle.MutableLiveData.setValue(MutableLiveData.java:33)
at org.Foo.<init>(Foo.kt:10)
at org.FooTest.ShouldNotBlowUp(FooTest.kt:3)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
如何初始化 ArrayList 并将其设置为 bars
的值?
可能是因为您正试图 运行 在测试中这样做。您的示例在 DefaultTaskExecutor.isMainThread() 中失败,看起来像这样:
public boolean isMainThread() {
return Looper.getMainLooper().getThread() == Thread.currentThread();
}
所以Looper.getMainLooper()returns在测试环境下为null
此外,您是否尝试通过 'lazy' 委托初始化 属性?
val bars: MutableLiveData<List<Bar>> by lazy {
MutableLiveData<List<Bar>>().apply {
value = emptyList()
}
}
这对我来说效果很好,而且感觉更地道
问题的答案是:如果你明明想给它一个空值,但是变量不为空,你至少可以在不破坏程序的情况下使用它。
创建一个变量:
val myVariable = MutableLiveData<ArrayList<String>>()
好吧,现在你只需要在类型括号内传递空列表的构造函数,这样你的变量就不会保持空值。
val myVariable = MutableLiveData<ArrayList<String>>(arrayListOf())
我知道这是一个老问题,但如果它可以帮助某人,它帮助我发现了这一点;)