前言
项目实际场景中存在无网或弱网环境中操作记录。应用程序是这样工作的:
- 有网络:执行networkapi
- 弱网或无网络:把需要提交的数据保存到room中,使用WorkManager将任务加入任务队列,然后在网络连接时发送请求
下图为项目中提交记录运用Room本地存储和Workmanager进行任务队列
Step1.弱网或无网络本地数据存储(Room)
1.网络判断
-
无网络
mTopBar.addRightTextButton("提交", R.id.RIGHT).setOnClickListener { if (NetworkUtil.isNetworkAvailable(baseContext)) { goCommit() } else { insertLocalDB() } }
-
弱网(网络超时,且当客户端发生弱网)
ApiServerResponse .getInstence() .createEffectRecord(map, object : RetrofitObserver<BaseResponse<Any>>(this) { override fun onSuccess(response: BaseResponse<Any>) { dismiss() showToast("创建成功") finish() } override fun onNetError(e: Throwable) { dismiss() insertLocalDB() ExceptionHandle.handleException(e) } })
2.插入数据,开启后台任务
/**
* 无网络提交本地数据库
* */
private fun insertLocalDB() {
val record = Record('','','',...)
//插入数据
PmpDataBase.getInstance(baseContext).planDao().insertRecord(record)
//判断是否已开启后台服务
val hasLocalRecord: Boolean = MMKVUtil.decodeBoolean(Constants.SP_KEY_LOCAL_RECORD)!!
LogUtils.d("RecordLocalRecord", hasLocalRecord)
if (!hasLocalRecord) {
//没开启就去开启
MMKVUtil.encode(Constants.SP_KEY_LOCAL_RECORD, true)
val request = OneTimeWorkRequest.Builder(RecordWorker::class.java)
.setConstraints(getConstraints())
.build()
//队列
WorkManager.getInstance(this@CycleEffectActivity).enqueue(request)
WorkManager.getInstance(this@CycleEffectActivity)
.getWorkInfoByIdLiveData(request.id)
.observe(this@CycleEffectActivity, {//通过id
if (it != null && it.state.isFinished) {
LogUtils.d("RecordDoWorkResult", "success")
MMKVUtil.encode(Constants.SP_KEY_LOCAL_RECORD, false)
WorkManager.getInstance(this@CycleEffectActivity)
.cancelWorkById(request.id)
}
})
}
}
/**
* Constraints
**/
private fun getConstaints():Constraints{
return Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED) // 网络状态
.setRequiresBatteryNotLow(true) // 不在电量不足时执行
.setRequiresCharging(true) // 在充电时执行
.setRequiresStorageNotLow(true) // 不在存储容量不足时执行
.setRequiresDeviceIdle(true) // 在待机状态下执行,须要 API 23
.build()
}
Step2.后台任务调度(WorkManager)
无论应用程序进程是否存在,WorkManager都会处理在满足各种约束条件时需要运行的后台工作。
后台工作可以在应用程序位于后台、前台或者应用在前台打开即将转到后台的时候启动。
无论应用程序在做什么,后台工作都应该继续进行,或者在 Android 终止其进程时重启其后台工作。
WorkManager设计用于在满足某些条件时执行操作(e.g.:有网络状态时,不在电量不足时执行,在充电时执行等)
/**
* @作者 : JayGengi
* @时间 : 2022/3/17 9:38
* @描述 : 记录【record】后台任务:本地room db文件 记录内容提交服务器
*/
class RecordWorker(var context: Context, workerParams: WorkerParameters) :
Worker(context, workerParams) {
override fun doWork(): Result {
//接收传递过来的数据
LogUtils.d("RecordDoWork1")
return try {
val localRecordList = PmpDataBase.getInstance(context)
.planDao().localRecordList as ArrayList<Record>
LogUtils.d("RecordDoWorkListSize", localRecordList.size.toString() + "")
if (null != localRecordList && localRecordList.size > 0) {
//执行
submitLocalDBRecord(localRecordList)
}
Result.success()
} catch (exception: Exception) {
LogUtils.d("RecordDoWorkFailure")
exception.printStackTrace()
Result.failure()
}
}
网友评论