onCreate中执行Firebase查询导致Activity启动过慢如何解决
Activity启动耗时过长问题修复方案
你当前的实现本质是把网络请求、数据解析全流程和页面渲染强绑定,用户必须等所有数据加载完成才能看到页面内容,自然启动耗时极长,按以下步骤修改即可:
- 首先解除启动流程对Firebase请求的强依赖:不要等请求返回才调用
main()做UI初始化,进入Activity先渲染基础UI、展示轻量loading占位,闪屏页增加2s超时兜底,到点直接进主页,数据加载完成后再刷新内容,不要死等网络。 - 修正协程使用方式:不要手动创建无生命周期绑定的
CoroutineScope(Dispatchers.IO),换成Activity自带的lifecycleScope,避免内存泄漏;数据解析、去重逻辑明确放在IO线程执行,仅UI更新操作切回主线程。 - 优化数据处理逻辑:原代码用
ArrayList.contains()做去重是O(n²)时间复杂度,换成HashSet做判重,性能提升明显;数据加载完成后只做列表数据更新、通知适配器刷新即可,不要重复执行整个main()的UI初始化逻辑。 - 利用Firestore本地缓存提速:给查询加快照监听,冷启动时优先读取本地缓存的历史数据瞬间渲染,后台自动同步最新网络数据,用户无加载感知。
优化后的参考代码:
private fun getAngryMovies() { // 进入页面先初始化基础UI,不等待数据加载 main() showContent = false lifecycleScope.launch { val movieResult = withContext(Dispatchers.IO) { val querySnapshot = allMoviesCollectionReference .whereEqualTo("type", "Angry") .get() .await() // 用HashSet做O(1)时间复杂度去重 val tempSet = hashSetOf<AngryMovies2>() querySnapshot.documents.forEach { doc -> doc.toObject<AngryMovies2>()?.let { tempSet.add(it) } } tempSet.toList() } // 主线程更新数据 innerAngryMovieList.clear() innerAngryMovieList.addAll(movieResult) showContent = true // 仅刷新列表,不重复初始化整个UI movieAdapter.notifyDataSetChanged() } }
如果要做极致体验,可以把查询时机延后:如果该电影列表不是用户进入页面首屏可见内容,等首帧渲染完成、用户滑动到对应区域时再触发请求,进一步缩短启动耗时。
内容的提问来源于stack exchange,提问作者user18145931
相关产品推荐
相关产品推荐

