zoukankan      html  css  js  c++  java
  • Android WorkManager工作约束,延迟与查询工作

    WorkManager工作约束,延迟与查询工作

    本文可能会混用“工作”与“任务”这两个词。
    本文例子使用Kotlin

    准备一个工作类(任务)UploadWorker2

    class UploadWorker2(context: Context, params: WorkerParameters) : Worker(context, params) {
        override fun doWork(): Result {
            Log.d(TAG, "模拟执行任务2 ${Thread.currentThread()}")
            return Result.success()
        }
    }
    

    工作约束

    约束可让工作延迟到满足最佳条件时运行。下面的约束适用于 WorkManager

    名称 说明
    NetworkType 约束运行工作所需的网络类型。例如 Wi-Fi (UNMETERED)。
    BatteryNotLow 若为 true,那么当设备处于“电量不足模式”时,工作不会运行。
    RequiresCharging 若为 true,那么工作只能在设备充电时运行。
    DeviceIdle 若为 true,则设备必须处于空闲状态才能运行工作。如果考虑到其他应用的性能,建议用这个约束。
    StorageNotLow 若为 true,那么当设备上的存储空间不足时,工作不会运行。

    可用Constraints.Builder()来创建工作约束。然后将Constraints实例分配给WorkRequest.Builder()
    也就是说,工作约束是针对工作WorkRequest的。

    下面这个工作约束,只有1个要求,在设备使用计费流量是执行任务。

    val constraints = Constraints.Builder()
            .setRequiredNetworkType(NetworkType.METERED)
            .build()
    val d1 = OneTimeWorkRequest.Builder(UploadWorker2::class.java)
            .setConstraints(constraints)
            .addTag("约束").build()
    mIdList.add(d1.id) // 登记任务id,可去掉
    WorkManager.getInstance(applicationContext).enqueue(d1)
    

    真机测试中,如果一开始手机用着wifi,那么任务不会执行。而关掉wifi,打开流量开关,就会执行任务。
    这就是满足最佳条件时运行。

    NetworkType说明

    androidx.work.NetworkType是一个枚举类。目前有

    枚举 说明
    NOT_REQUIRED 这个工作不需要网络
    CONNECTED 这个工作需要有网络连接
    UNMETERED 需要Wi-Fi
    NOT_ROAMING 非漫游网络
    METERED 需要按流量计费的网络

    延迟工作

    如果工作没有约束,或者当工作加入队列时所有约束都得到了满足,那么系统可能会选择立即运行该工作。
    如果不希望工作立即运行,可以给工作设定一个延迟时间。

    下面这个工作是要延迟3秒钟。

    val d1 = OneTimeWorkRequest.Builder(UploadWorker2::class.java)
            .addTag("延迟1")
            .setInitialDelay(3, TimeUnit.SECONDS)
            .build()
    WorkManager.getInstance(applicationContext).enqueue(d1)
    

    enqueue任务后,查一下任务状态。工作从ENQUEUED状态,执行完毕后变成了SUCCEEDED

    WorkInfo{mId='2794b4dd-7c02-4fd0-9851-8798a0da3bb2', mState=ENQUEUED, mOutputData=Data {}, mTags=[com.rustfisher.tutorial2020.workmanaer.WorkManagerAct$UploadWorker2, 延迟1], mProgress=Data {}}
    
    WorkInfo{mId='2794b4dd-7c02-4fd0-9851-8798a0da3bb2', mState=SUCCEEDED, mOutputData=Data {}, mTags=[com.rustfisher.tutorial2020.workmanaer.WorkManagerAct$UploadWorker2, 延迟1], mProgress=Data {}}
    

    查询工作

    使用UUID查询

    新建工作的时候,系统会分配一个UUID。我们可以记录UUID到mIdList里。通过UUID可以查询到工作当前的状态。

    val mgr = WorkManager.getInstance(applicationContext)
    for (id in mIdList) {
        val cur = mgr.getWorkInfoById(id)
        Log.d(TAG, "查询任务 ${cur.get()}")
    }
    

    一个工作状态的例子,状态是ENQUEUED

    WorkInfo{mId='16cc292d-f140-488f-9ab5-a0d22b95d128', mState=ENQUEUED, mOutputData=Data {}, mTags=[com.rustfisher.tutorial2020.workmanaer.WorkManagerAct$UploadWorker, r1], mProgress=Data {}}
    

    使用tag查询

    前面我们给工作打上tag。可以用WorkManagergetWorkInfosByTag()方法把指定tag的工作查出来。

    val mgr = WorkManager.getInstance(applicationContext)
    
    for (w in mgr.getWorkInfosByTag("约束1").get()) {
        Log.d(TAG, "$w")
    }
    

    工作状态的例子,下面这个工作UploadWorker状态是SUCCEEDED,tag里有约束1

    WorkInfo{mId='fed1974c-77e5-46ba-8b38-f6c01d68fe4c', mState=SUCCEEDED, mOutputData=Data {}, mTags=[com.rustfisher.tutorial2020.workmanaer.WorkManagerAct$UploadWorker, 约束1], mProgress=Data {}}
    

    需要注意的是,工作的状态是存储起来的。即使重启app或者手机,都可以查到这个工作的状态。
    假设查询tag是约束1,我们能得到之前创建的含有这个约束1标签的工作。

    参考

    一个软件工程师的记录
  • 相关阅读:
    C#基础篇——泛型
    基于.NetCore3.1系列 —— 使用Swagger导出文档 (补充篇)
    基于.NetCore3.1系列 —— 使用Swagger导出文档 (番外篇)
    springboot深入浅出系列(16章97节)-看了都说好
    小书MybatisPlus第5篇-Active Record模式精讲
    小书MybatisPlus第4篇-表格分页与下拉分页查询
    使用位运算、值交换等方式反转java字符串-共四种方法
    有效提高java编程安全性的12条黄金法则
    小书MybatisPlus第3篇-自定义SQL
    结合SpEL使用@Value-基于配置文件或非配置的文件的值注入-Spring Boot
  • 原文地址:https://www.cnblogs.com/rustfisher/p/15174577.html
Copyright © 2011-2022 走看看