面试题答案
一键面试避免任务重复执行
- 使用
ExistingWorkPolicy
:WorkManager
提供了ExistingWorkPolicy
来处理已存在的相同任务。可以通过WorkManager.getInstance(context).enqueueUniqueWork
方法来使用。- 例如,假设我们有一个名为
SyncDataWork
的Worker
类,要确保同步数据任务不会重复执行:
val constraints = Constraints.Builder() .setRequiredNetworkType(NetworkType.CONNECTED) .build() val work = OneTimeWorkRequestBuilder<SyncDataWork>() .setConstraints(constraints) .build() WorkManager.getInstance(context).enqueueUniqueWork( "sync_data_work", ExistingWorkPolicy.REPLACE, work )
- 在上述代码中,
ExistingWorkPolicy.REPLACE
表示如果已经有一个名为sync_data_work
的任务在队列中,新提交的任务会替换旧任务。其他可选的策略还有ExistingWorkPolicy.KEEP
(保留旧任务,忽略新任务)和ExistingWorkPolicy.APPEND
(将新任务追加到旧任务之后)。
合理设置任务优先级
- 使用
setInitialDelay
和setBackoffCriteria
:- 对于任务优先级,可以通过设置任务的初始延迟和退避策略来间接影响任务执行顺序。
- 例如,对于一些非紧急但重要的任务,可以设置一定的初始延迟:
val constraints = Constraints.Builder() .setRequiredNetworkType(NetworkType.CONNECTED) .build() val work = OneTimeWorkRequestBuilder<NonUrgentWork>() .setConstraints(constraints) .setInitialDelay(15, TimeUnit.MINUTES) .build() WorkManager.getInstance(context).enqueue(work)
- 对于需要重试的任务,可以设置退避策略。假设任务执行失败后需要重试,且每次重试间隔逐渐增加:
val constraints = Constraints.Builder() .setRequiredNetworkType(NetworkType.CONNECTED) .build() val work = OneTimeWorkRequestBuilder<RetryableWork>() .setConstraints(constraints) .setBackoffCriteria( BackoffPolicy.EXPONENTIAL, OneTimeWorkRequest.MIN_BACKOFF_MILLIS, TimeUnit.MILLISECONDS ) .build() WorkManager.getInstance(context).enqueue(work)
- 在上述代码中,
BackoffPolicy.EXPONENTIAL
表示退避策略为指数增长,OneTimeWorkRequest.MIN_BACKOFF_MILLIS
是初始退避时间。
异常处理
- 在
Worker
类中处理异常:- 在
Worker
的doWork
方法中,通过try - catch
块捕获异常,并返回合适的Result
。 - 例如:
class MyWorker(appContext: Context, workerParams: WorkerParameters) : Worker(appContext, workerParams) { override fun doWork(): Result { return try { // 执行任务的代码 // 如果任务成功完成 Result.success() } catch (e: Exception) { // 处理异常 Log.e("MyWorker", "Task execution failed", e) // 根据异常情况返回合适的结果 Result.failure() } } }
- 在
- 在调用处监听任务状态:
- 通过
WorkManager.getInstance(context).getWorkInfoByIdLiveData(workId)
监听任务状态,处理异常情况。
val workInfoLiveData = WorkManager.getInstance(context).getWorkInfoByIdLiveData(workId) workInfoLiveData.observe(owner, Observer { workInfo -> if (workInfo != null && workInfo.state.isFinished) { if (workInfo.state == WorkInfo.State.FAILED) { // 任务失败,处理异常 Log.e("WorkManager", "Task with id $workId failed") } } })
- 这样可以在任务执行失败时,在调用处进行相应的处理,比如提示用户或者进行其他补救措施,以确保应用的稳定性和数据的完整性。
- 通过