滑动不卡顿
首帧无黑屏
冷启动秒开
弱网可用
后台上传不断
最近从 0 到 1 做了一个 Android 短视频 App,完整实现:
- 视频流播放
- 分页加载
- 本地缓存
- 拍摄上传
- 崩溃监控
- 后台断点续传
这篇文章不讲 Demo,而是讲:
👉 真实项目架构 + 性能优化方案 + 踩坑总结
🚀 一、技术栈(生产级配置)
Kotlin 2.3
AGP 8.13
MVVM + Repository
Hilt 依赖注入
Retrofit3 + OkHttp5
Paging3 + Room
ExoPlayer
CameraX
WorkManager
DataStore
Firebase Crashlytics
🚀 二、整体架构设计
项目采用经典分层架构:
UI (Activity / Fragment)
↓
ViewModel
↓
Repository
↓ ↓
Remote Local
(Retrofit) (Room)
👉 为什么必须这样分层?
短视频应用天然具备几个特点:
-
数据量大
-
滑动频繁
-
网络波动明显
-
播放器占用资源高
-
生命周期复杂
-
如果所有逻辑堆在 UI 层:
-
代码会迅速失控
-
难以维护
-
极难排查性能问题
Repository 层的存在,让:
-
网络与缓存逻辑解耦
-
数据流更加清晰
-
更容易做单元测试
🎬 三、视频播放核心设计(ExoPlayer 优化)
短视频 App 的灵魂是播放器管理。
真正的难点不在“播放”,而在:
-
如何切换流畅
-
如何减少黑屏
-
如何避免内存暴涨
-
如何处理 RecyclerView 生命周期
📈 十大核心优化总结(短视频 App 实战)
1️⃣ 单播放器复用
- 全局只维护一个 ExoPlayer
- RecyclerView 中动态 attach / detach
- 不重复创建播放器
效果:
- 内存降低约 30%
- 减少 GC
- 滑动更流畅
2️⃣ 视频预加载机制
- 当前播放 index
- 预加载 index + 1
- 使用 CacheDataSource 做本地缓存
效果:
- 首帧时间明显缩短
- 基本无黑屏
- 弱网体验更稳定
3️⃣ Paging3 + RemoteMediator
- 自动分页
- 网络 + 本地缓存协调
- 支持刷新和离线模式
效果:
- 列表稳定
- 状态清晰
- 不易重复请求
4️⃣ Room 本地缓存策略
- 冷启动直接展示缓存
- 使用 RemoteKey 管理分页位置
效果:
- 冷启动秒开
- 弱网可浏览
5️⃣ 协程并发优化首页
- async 并发加载 Banner / 推荐流 / 分类
- 避免串行请求
效果:
- 首屏加载时间减少约 35%
- 用户等待感降低
6️⃣ CameraX 生命周期绑定
- 使用 bindToLifecycle
- 自动管理摄像头资源
效果:
- 设备兼容性更好
- 减少崩溃概率
7️⃣ WorkManager 后台上传
- 网络约束
- 断点重试
- 唯一任务控制
效果:
- 上传可靠
- 进程重启可恢复
- 避免重复执行
8️⃣ 生命周期精细化管理
- onPause 暂停播放
- onStop 释放资源
- detach Surface 避免泄漏
效果:
- 避免内存泄漏
- 防止异常播放
9️⃣ DiffUtil 优化刷新闪屏
- 避免全量刷新
- 减少 UI 抖动
效果:
- 列表更稳定
- 无闪屏问题
🔟 Crashlytics 线上监控
- 收集崩溃日志
- 分析设备分布
- 快速定位异常
效果:
- 提升线上稳定性
- 快速修复问题
🏁 总结一句话
短视频 App 的本质不是“播放视频”,
而是:
列表性能 + 播放器管理 + 数据流设计 + 生命周期控制 + 资源调度能力