首页 > 解决方案 > 在 for 循环中解构时尝试调用空对象

问题描述

这怎么可能?

在后台线程上,我正在运行一些填充列表的计算,然后使视图无效,并且视图运行 onDraw。

var list = mutableListOf<Pair<DataPoint, String>>()

...

generateBgData() {
    list.clear()
    list.add(...,...)
    invalidate()
}

在onDraw中,我对列表进行了复制,以防止更新列表导致错误,

    val listCopy = ArrayList(list)
    for ((point, str)in listCopy) { // Null exception thrown here
        canvas.drawText(...)
    }

但在指出的那一行,我在解构时遇到空对象引用错误java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object kotlin.Pair.component1()' on a null object reference。这怎么可能?我的列表是非空的,我从来没有将列表设置为空。如果它为空,则 for 循环永远不会运行。我在这里重新创建了运行问题的代码,但无法复制它,但它在我的应用商店中很少发生。

知道可能发生什么吗?

标签: javaandroidkotlin

解决方案


多线程可能是罪魁祸首。想象一下,当这段代码运行时,您的列表中有一些项目:

val listCopy = ArrayList(list)

当 ArrayList 构造函数从列表中复制项目时,另一个线程会清除列表,这会将所有内容标记为空。如果另一个线程清除列表的速度比该线程复制引用的速度快,它将开始为列表中的最后一项复制空引用。

如果您要从多个线程修改数据,我建议专门使用只读列表。


推荐阅读