Kotlin中Firestore文档存入ArrayList方法及日志顺序异常求助
Firestore文档数据存入ArrayList问题解答
疑问1:为什么Log.d("yool", ret.toString())的输出比Log.d("yool", current.toString())更快?
Firestore的get()是异步非阻塞的网络请求,它不会卡住当前主线程。代码的实际执行顺序是:
- 创建空的
ret集合 - 发起Firestore请求后,立刻跳过回调代码,继续执行
Log.d("yool", ret.toString())并返回空集合 - 等Firestore请求成功拿到数据后,才会进入
addOnSuccessListener回调,把数据添加到ret并打印current.toString()
所以日志顺序会反过来——同步代码先执行,异步回调的代码后执行。
疑问2:如何正确从Firestore获取对象并存入ArrayList?
因为Firestore操作是异步的,不能像同步代码那样直接返回结果,推荐用Kotlin协程处理,代码更简洁易读:
修改后的完整代码
class AddActivity : AppCompatActivity() { val mainDataBase = FirebaseFirestore.getInstance().collection("mainDB") val customDataBase = FirebaseFirestore.getInstance().collection("customDB") // 将方法改为挂起函数,用协程等待异步请求完成 private suspend fun getMainList(): ArrayList<ExerciseDataBase> { val ret = ArrayList<ExerciseDataBase>() try { // 用await()阻塞当前协程,等待Firestore请求返回结果 val documents = mainDataBase.get().await() for (document in documents) { val current = document.toObject(ExerciseDataBase::class.java) Log.d("yool", current.toString()) ret.add(current) } } catch (e: Exception) { Log.d("yool", "return fail", e) } Log.d("yool", ret.toString()) return ret } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val addBinding = ActivityAddBinding.inflate(layoutInflater) setContentView(addBinding.root) // 在Activity的生命周期协程作用域中调用挂起函数 lifecycleScope.launch { val list: ArrayList<ExerciseDataBase> = getMainList() Log.d("yool", list.toString()) // 拿到数据后可在此做后续操作,比如给RecyclerView的Adapter赋值 } } }
关键说明
- 需确保项目引入Firestore协程依赖:
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.7.3"(版本可根据项目调整) - 使用
lifecycleScope是因为它和Activity生命周期绑定,能自动销毁协程,避免内存泄漏 - 也可以用回调接口或LiveData处理异步结果,但协程是Kotlin中最简洁的异步处理方案
内容的提问来源于stack exchange,提问作者hilaw00
相关产品推荐
相关产品推荐

