【问题标题】:How to wait the end of a firebase call in Kotlin (Android)如何在 Kotlin (Android) 中等待 firebase 调用结束
【发布时间】:2019-08-21 19:28:11
【问题描述】:

在一个 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
    }

感谢您的帮助!

【问题讨论】:

    标签: android multithreading kotlin coroutine


    【解决方案1】:

    您可以使用 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)。

    【讨论】:

      猜你喜欢
      • 2014-11-27
      • 2021-05-13
      • 2012-07-13
      • 1970-01-01
      • 1970-01-01
      • 2023-03-05
      • 1970-01-01
      • 2017-05-28
      • 2022-11-11
      相关资源
      最近更新 更多