【问题标题】:Why is the following function returning null ArrayList?为什么以下函数返回 null ArrayList?
【发布时间】:2020-02-24 20:38:33
【问题描述】:

我什至使用过 List,但仍然得到空指针,但如果我使用 livedata,它会在 for 循环内成功更新。它不返回空值。为什么只有返回 null 的 list 或 Arraylist

  fun List(): ArrayList<Bank> {
    val banklist = ArrayList<Bank>()
    val reference = FirebaseDatabase.getInstance().reference
        .child("groups")
        .child(group.group_id)
        .child("financials")
        .child("cash")
        .child("bank")
    reference.addValueEventListener(object : ValueEventListener {

        override fun onCancelled(p0: DatabaseError) {

        }

        override fun onDataChange(dataSnapshot: DataSnapshot) {

            for (singleSnapshot in dataSnapshot.children) {
                Log.d(
                    "Data", "banks found: "
                            + singleSnapshot.value
                )
                val bank = singleSnapshot.getValue(Bank::class.java)
                banklist.add(bank!!)

               bankListLivedata.value = banklist //updates perfectly

            }


            Log.d(
                "Data", "banksList1 ${banklist[0].bank_account} "//This is printing in the log

            )

        }
    }
    )
    Log.d(
        "Data", "banksList2 ${banklist[0].bank_account} " //This is throwing null pointer exception

    )

    return banklist //this is null

  //if I return banklistLivedata it works perfectly and doesn't throw null
}

【问题讨论】:

  • 您能否添加更多信息,显示您如何调用此函数以及异常发生的位置以及您收到的异常消息。就目前而言,我无法重现您遇到的错误
  • val list = list() if (list.isNullOrEmpty()) { Log.d("CashActivity", "List Null") } else { Log.d("CashActivity", "List $ {list[0].bank_account}") } 日志打印为空
  • 这是有道理的。 isNullOrEmpty() 适用于 null 列表,如果列表为 null 或为空,则返回 true(就像名字所说的那样)。因此,正如当前答案所暗示的那样,您的列表确实为空,这是因为它从未在函数调用中返回。当我说“它为空”时,我的意思是在函数之外,即期望从此函数获取列表的接收器对象为空
  • @smac89 谢谢,所以没有解决办法?
  • 解决方案很简单:在尝试记录其第一个元素 (Log.d("Data", "banksList1 ${banklist[0].bank_account} ")) 之前检查您的 banklist(函数内部)是否有任何数据(Log.d("Data", "banksList1 ${banklist[0].bank_account} ")

标签: arrays list kotlin arraylist


【解决方案1】:

您的日志记录中抛出的 NPE 是因为 banklist 在更改侦听器中被修改。

Log.d(
        "Data", "banksList2 ${banklist[0].bank_account} " //This is throwing null pointer exception

    )

如果没有进行任何更改,或者在侦听器内部,可迭代的 dataSnapshot.children 为空 - banklist 保持为空。因此,当您调用 list[index] 时,它将返回 null,因为没有找到任何东西,并且它会抛出 NPE,因为您在 null 上调用 .bank_account


return banklist //this is null

我很确定您方法末尾的 banklistnot null。因为之前的代码抛出异常,所以这部分永远不会到达。

【讨论】:

  • 刚刚确认为空。我只是打电话给它并检查它是否为空,是的,它是空的。我不明白您的评论,因为该列表与日志位于同一部分。
  • @coder254 您必须在函数外部检查它是否为空,而不是从函数内部检查。它是空的,因为该部分从未达到此答案状态。所以它没有被退回。
  • 我在函数之外这样做了。我从另一个函数调用了该函数
  • @coder254 调用 ValueEventListener 时,在您使用 fun List() 创建它时,它的旧值/引用为 banklist。在此调用期间(侦听器)范围之外,banklist 不存在 - 所以null
  • @coder254 你想在fun List() 中返回什么?据我所知,banklist 将始终为空。如果要从每个事件中收集值,请将 banklist 作为字段存储在伴随对象中。如果您只是想避免 NPE,请使用 @smac89 answer firstOrNull
【解决方案2】:

解决方案是确保在尝试记录之前检查列表是否为空,或者更好的是使用 Kotlin 的实用方法之一(如 firstOrNull())来检索列表的第一个元素:

Log.d("Data", "banksList2 ${banklist.firstOrNull()?.bank_account} ")

我还建议对侦听器内部的日志记录执行相同的操作:

Log.d("Data", "banksList1 ${banklist.firstOrNull()?.bank_account} ")

【讨论】:

  • 另外,如果我使用 livedata,我将获取列表的实时数据。它完美地返回它。
猜你喜欢
  • 2016-07-25
  • 2013-03-30
  • 1970-01-01
  • 1970-01-01
  • 2017-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多