上一篇
安卓开发定时获取网络数据
- 行业动态
- 2025-04-21
- 2
实现定时任务的核心组件
安卓中实现定时任务主要依赖以下组件:
组件 | 适用场景 | 最小API支持 |
---|---|---|
AlarmManager | 精确定时唤醒(需处理系统杀进程问题) | API 1 |
JobScheduler | 系统级调度(API 21+) | API 21 |
WorkManager | 兼容各版本、可靠执行(推荐) | API 14 |
Handler.postDelayed | 短时间延迟任务(不适用于跨进程/被杀情况) | API 1 |
RxJava/Coroutine | 基于时间轴的轮询(需配合前台服务) |
网络请求最佳实践
网络层封装
建议使用Retrofit
+OkHttp
组合,配置示例:val retrofit = Retrofit.Builder() .baseUrl("https://api.example.com") .addConverterFactory(GsonConverterFactory.create()) .client(OkHttpClient.Builder() .readTimeout(10, TimeUnit.SECONDS) .build()) .build()
协程异步处理
使用Kotlin协程简化异步代码:viewModelScope.launch { try { val data = withContext(Dispatchers.IO) { apiService.getData() } // 更新UI } catch (e: Exception) { // 错误处理 } }
定时任务与网络请求整合方案
方案对比表
方案 | 可靠性 | 存活能力 | 开发难度 | 适用场景 |
---|---|---|---|---|
AlarmManager+IntentService | 中 | 低 | 简单 | 简单定时任务(需保活) |
JobScheduler+Coroutine | 高 | 中 | 中等 | Android 7.0+系统级调度 |
WorkManager+Coroutine | 高 | 高 | 简单 | 全版本兼容、后台可靠执行 |
RxJava轮询 | 低 | 低 | 复杂 | 短周期实时性要求场景 |
推荐方案:WorkManager实现
// 定义Worker类 class FetchDataWorker(appContext: Context, params: WorkerParameters) : CoroutineWorker(appContext, params) { override suspend fun doWork(): Result { return try { // 执行网络请求 val data = apiService.getData() // 持久化或发送广播 Result.success() } catch (e: Exception) { Result.retry() } } } // 调度任务 val workRequest = OneTimeWorkRequestBuilder<FetchDataWorker>() .setInitialDelay(1, TimeUnit.HOURS) // 初始延迟 .setPeriodic(1, TimeUnit.HOURS) // 周期执行 .build() WorkManager.getInstance(context).enqueue(workRequest)
关键注意事项
进程被杀处理
- WorkManager会自动恢复未完成的任务
- 需在
AndroidManifest
添加:<service android:name="androidx.work.impl.background.systemalarm.RescheduleReceiver" android:exported="false" />
网络状态监听
val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager val network = connectivityManager.activeNetworkInfo if (network != null && network.isConnected) { // 执行网络请求 } else { // 延迟重试 WorkManager.getInstance(context).enqueue(workRequest.setBackoffCriteria(BackoffPolicy.LINEAR, 5, TimeUnit.MINUTES)) }
电量优化策略
- 设置合理周期(建议≥15分钟)
- 使用
setConstraints
限制只在充电/非省电模式运行:val constraints = Constraints.Builder() .setRequiresCharging(true) // 充电时执行 .build()
完整代码示例
// Build.gradle依赖 implementation "androidx.work:work-runtime-ktx:2.7.1" implementation "com.squareup.retrofit2:retrofit:2.9.0" implementation "org.jetbrains.kotlinx:kotlinx-coroutine-core:1.6.1" // Worker实现类 class DataSyncWorker(appContext: Context, params: WorkerParameters) : CoroutineWorker(appContext, params) { private val apiService: ApiService by lazy { Retrofit.Builder() .baseUrl("https://api.example.com") .addConverterFactory(GsonConverterFactory.create()) .build() .create(ApiService::class.java) } override suspend fun doWork(): Result { return withContext(Dispatchers.IO) { try { val response = apiService.fetchData() if (response.isSuccessful) { // 处理数据并持久化 Result.success() } else { Result.retry() } } catch (e: Exception) { Result.retry() } } } } // 调度逻辑 fun schedulePeriodicTask(context: Context) { val workRequest = PeriodicWorkRequestBuilder<DataSyncWorker>(1, TimeUnit.HOURS) .setConstraints(Constraints.Builder() .setRequiredNetworkType(NetworkType.CONNECTED) .setRequiresCharging(false) .build()) .setBackoffCriteria(BackoffPolicy.EXPONENTIAL, 1, TimeUnit.MINUTES) .build() WorkManager.getInstance(context).enqueue(workRequest) }
相关问题与解答
Q1:如何处理WorkManager任务被系统杀死后自动恢复?
A:WorkManager通过系统提供的JobScheduler
(API 23+)或AlarmManager
(API <23)实现持久化调度,当应用进程被杀死时,系统会保留调度信息,在进程重建后自动执行未完成的任务,开发者无需额外处理,但需确保Worker
类实现@Expose
注解字段(如果使用Parcelable参数)。
Q2:如何在定时任务中更新UI或发送通知?
A:由于Worker
运行在后台线程,直接更新UI会导致异常,推荐做法:
- 发送广播到前端:
context.sendBroadcast(Intent("ACTION_DATA_UPDATED").apply { putExtra("data", resultData) })
- 使用
LiveData
或ViewModel
观察数据变化(需结合前台Service) - 显示通知:
NotificationManagerCompat.from(context).notify(1, notificationBuilder.build())