美文网首页
Jetpack Room+WorkManager做本地存储和数据

Jetpack Room+WorkManager做本地存储和数据

作者: 我爱田Hebe | 来源:发表于2022-03-21 21:19 被阅读0次

    前言

    项目实际场景中存在无网或弱网环境中操作记录。应用程序是这样工作的:

    • 有网络:执行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()
            }
        }
    
    

    参考

    room-livedata-workmanager

    相关文章

      网友评论

          本文标题:Jetpack Room+WorkManager做本地存储和数据

          本文链接:https://www.haomeiwen.com/subject/orztjrtx.html