首页 > 解决方案 > 如何在 Kotlin(Android)中等待 firebase 调用结束

问题描述

在一个 android 应用程序中,我正在尝试执行一个填充 ArrayAdapter 的 firebase 调用,以显示船舶列表。当我使用本地 ArrayList 时,它可以工作,但我的 firebase 调用无法正常工作。因为firebase调用是异步的,android在结束firebase调用之前向我展示了应用程序,所以我的ArrayAdapter是空的,我的布局也是空的。我尝试使用我在网上看到的协程方法,但似乎不起作用。有人能帮我吗 ?这是我的源代码:

主要活动 :

    override fun onCreate(savedInstanceState: Bundle?){
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        var containerShips : List<Containership> = listOf()
        val db = Database()

        runBlocking {
            containerShips = db.getAllContainerships()
        }




        val arrayAdapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, containerShips)

        val listShipDetails = findViewById<ListView>(R.id.listShipDetails)

        listShipDetails.adapter = arrayAdapter

    }

数据库:

   suspend fun getAllContainerships() : List<Containership> {
        val list : MutableList<Containership> = mutableListOf()
        val job = GlobalScope.launch {
            db.collection("Containership").get().addOnSuccessListener { result ->
                for (containership in result) {
                    list.add(containership.toObject(Containership::class.java))
                    println(containership.toObject(Containership::class.java))
                }
            }
        }
        job.join()
        return list
    }

谢谢你的帮助 !

标签: androidmultithreadingkotlincoroutine

解决方案


您可以使用 Tasks.await 来完成这项工作。

private fun getAllContainerships(): List<Containership>  {
    return try {
        val taskResult = Tasks.await(db.collection("Containership").get(), 2, TimeUnit.SECONDS)
        taskResult.mapTo(ArrayList()) { containership.toObject(Containership::class.java) }, null)
    } catch (e: ExecutionException) {
        //TODO handle exception
    } catch (e: InterruptedException) {
        //TODO handle exception
    } catch (e: TimeoutException) {
        //TODO handle exception
    }
}

确保这是在后台线程中完成的。此外,尝试摆脱您的 GlobalScope.async,因为它是代码异味(为此,您可以使用 MVVM 模式,将数据访问代码放在视图模型中,并使用 AndroidX 生命周期中的 viewModelScope)。


推荐阅读