1. WorkManager 适用场景
1.1 需要保证执行的任务
场景:数据同步、日志上传、文件下载
Kotlin
// 场景:用户上传照片,需要保证最终上传成功
class PhotoUploadWorker(context: Context, params: WorkerParameters) : Worker(context, params) {
override fun doWork(): Result {
return try {
val photoPath = inputData.getString("photo_path") ?: return Result.failure()
// 上传照片
uploadPhoto(photoPath)
// 即使应用被杀死,任务也会在系统允许时重试
Result.success()
} catch (e: Exception) {
// 失败时会自动重试
Result.retry()
}
}
}
// 使用 WorkManager
val uploadWork = OneTimeWorkRequestBuilder<PhotoUploadWorker>()
.setInputData(Data.Builder().putString("photo_path", path).build())
.setConstraints(
Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build()
)
.build()
WorkManager.getInstance(context).enqueue(uploadWork)
为什么选择 WorkManager:
- ✅ 应用被杀死后任务仍会执行
- ✅ 系统会自动处理重试
- ✅ 支持网络、充电等约束条件
1.2 周期性任务
场景:定时同步、定时清理、定时备份
Kotlin
// 场景:每天凌晨2点同步用户数据
val syncWork = PeriodicWorkRequestBuilder<DataSyncWorker>(
1, TimeUnit.DAYS // 每天执行一次
).setConstraints(
Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.setRequiresDeviceIdle(true) // 设备空闲时执行
.build()
).build()
WorkManager.getInstance(context).enqueueUniquePeriodicWork(
"daily_sync",
ExistingPeriodicWorkPolicy.KEEP,
syncWork
)
为什么选择 WorkManager:
- ✅ 系统保证周期性执行
- ✅ 不受应用生命周期影响
- ✅ 支持系统级约束(空闲、充电等)
1.3 后台任务(应用不可见时)
场景:数据预处理、缓存清理、日志收集
Kotlin
// 场景:应用进入后台时收集使用数据
class AnalyticsWorker(context: Context, params: WorkerParameters) : Worker(context, params) {
override fun doWork(): Result {
return try {
// 收集用户行为数据
collectUserBehavior()
// 上传到服务器
uploadAnalytics()
Result.success()
} catch (e: Exception) {
Result.failure()
}
}
}
为什么选择 WorkManager:
- ✅ 应用在后台时仍能执行
- ✅ 系统会优化执行时机
- ✅ 不会影响用户体验
2. Flow 适用场景
2.1 实时数据流
场景:网络请求、数据库查询、传感器数据
Kotlin
// 场景:实时获取用户位置
class LocationRepository {
fun getLocationUpdates(): Flow<Location> = flow {
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
1000L, // 1秒更新一次
10f
) { location ->
emit(location)
}
}
.flowOn(Dispatchers.IO)
}
// 在 ViewModel 中使用
class LocationViewModel : ViewModel() {
private val _location = MutableStateFlow<Location?>(null)
val location: StateFlow<Location?> = _location.asStateFlow()
fun startLocationUpdates() {
locationRepository.getLocationUpdates()
.onEach { location ->
_location.value = location
}
.launchIn(viewModelScope)
}
}
为什么选择 Flow:
- ✅ 实时响应数据变化
- ✅ 易于取消和重新订阅
- ✅ 支持背压处理
2.2 UI 状态管理
场景:界面状态、用户输入、动画进度
Kotlin
// 场景:搜索功能
class SearchViewModel : ViewModel() {
private val _searchQuery = MutableStateFlow("")
val searchQuery: StateFlow<String> = _searchQuery.asStateFlow()
private val _searchResults = MutableStateFlow<List<Item>>(emptyList())
val searchResults: StateFlow<List<Item>> = _searchResults.asStateFlow()
fun search(query: String) {
_searchQuery.value = query
// 防抖搜索
searchQuery
.debounce(300) // 300ms 防抖
.filter { it.length >= 2 } // 至少2个字符
.flatMapLatest { query ->
searchRepository.search(query)
}
.onEach { results ->
_searchResults.value = results
}
.launchIn(viewModelScope)
}
}
为什么选择 Flow:
- ✅ 响应式编程
- ✅ 支持复杂的数据转换
- ✅ 易于测试
2.3 网络请求和数据处理
场景:API 调用、数据转换、缓存
Kotlin
// 场景:获取用户信息并处理
class UserRepository {
fun getUserInfo(userId: String): Flow<UserInfo> = flow {
// 先从缓存获取
val cachedUser = userCache.getUser(userId)
emit(cachedUser)
// 从网络获取最新数据
val networkUser = apiService.getUser(userId)
emit(networkUser)
// 更新缓存
userCache.saveUser(networkUser)
}
.catch { e ->
// 网络失败时使用缓存数据
val cachedUser = userCache.getUser(userId)
if (cachedUser != null) {
emit(cachedUser)
} else {
throw e
}
}
.flowOn(Dispatchers.IO)
}
为什么选择 Flow:
- ✅ 支持多数据源
- ✅ 易于处理错误
- ✅ 支持数据转换
3. 选择指南
3.1 选择 WorkManager 的场景
// ✅ 需要保证执行的任务
文件上传/下载
数据同步
日志上传
备份任务
// ✅ 周期性任务
定时清理
定时同步
定时备份
// ✅ 应用不可见时的任务
数据预处理
缓存清理
后台分析
// ✅ 需要系统约束的任务
仅在充电时执行
仅在 WiFi 下执行
仅在设备空闲时执行
3.2 选择 Flow 的场景
// ✅ 实时数据流
网络请求响应
数据库变化
传感器数据
用户输入
// ✅ UI 状态管理
界面状态
用户交互
动画进度
// ✅ 数据处理管道
数据转换
数据过滤
数据合并
// ✅ 响应式编程
事件驱动
状态管理
数据绑定
4. 实际项目中的选择策略
4.1 电商应用示例
Kotlin
// 使用 WorkManager 的场景
class OrderSyncWorker : Worker() {
override fun doWork(): Result {
// 同步订单状态
syncOrderStatus()
return Result.success()
}
}
// 使用 Flow 的场景
class ProductViewModel : ViewModel() {
private val _products = MutableStateFlow<List<Product>>(emptyList())
val products: StateFlow<List<Product>> = _products.asStateFlow()
fun searchProducts(query: String) {
productRepository.searchProducts(query)
.onEach { products ->
_products.value = products
}
.launchIn(viewModelScope)
}
}
4.2 社交媒体应用示例
Kotlin
// 使用 WorkManager 的场景
class MessageSyncWorker : Worker() {
override fun doWork(): Result {
// 同步离线消息
syncOfflineMessages()
return Result.success()
}
}
// 使用 Flow 的场景
class ChatViewModel : ViewModel() {
private val _messages = MutableStateFlow<List<Message>>(emptyList())
val messages: StateFlow<List<Message>> = _messages.asStateFlow()
fun observeMessages(chatId: String) {
messageRepository.getMessages(chatId)
.onEach { messages ->
_messages.value = messages
}
.launchIn(viewModelScope)
}
}
5. 总结
选择 WorkManager 当:
- 需要保证任务最终执行
- 任务需要在应用不可见时执行
- 需要系统级约束条件
- 周期性任务
- 应用被杀死后仍需执行的任务
选择 Flow 当:
- 实时数据流处理
- UI 状态管理
- 用户交互响应
- 数据处理管道
- 需要取消和重新订阅的场景
最佳实践:
- 在同一个项目中,WorkManager 和 Flow 可以结合使用
- WorkManager 负责后台任务调度
- Flow 负责实时数据流和 UI 状态管理
- 根据具体需求选择最合适的方案
这样选择可以确保应用的稳定性和用户体验!