如何为 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())

我知道这是一个老问题,但如果它可以帮助某人,它帮助我发现了这一点;)