WorkManager后台任务

介绍JetPack中的WorkManager

关于WorkManager的使用

本篇以Kotlin为主要语言

介绍

WorkManager是一个后台执行任务管理,即使在应用退出,也可以继续执行被创建的任务。还可以为WorkManager添加触发条件。当然还有特殊情况,当应用被彻底杀死的时候,任务是不会触发的,会等到下次应用开启,然后触发任务

  1. 添加依赖

    • 打开当前项目的ProjecySturcture

      image-20201224145447147

    • 在Dependencies.app中点击 + 来添加依赖,之后在Library Dependency中搜索androidx.work

      image-20201223092135741

    • 选择ktx结尾的,点击ok,等待下载完成

  2. 接下来创建一个类MyWorker 继承 Worker

    1
    2
    3
    4
    5
    6
    7
    8
    class MyWorker(context: Context, workerParams: WorkerParameters) : Worker(context, workerParams) {
    override fun doWork(): Result {
    Log.e("work", "doWork: $data 任务开始" )
    Thread.sleep(3000)
    Log.e("work", "doWork: $data 任务结束" )
    return Result.success()
    }
    }

    继承Worker 是需要传入参数,所以需要创建构造方法。这里为了方便观察,于是打印日志

  3. 然后再Activity中创建全局变量 workMananger,并且创建workRequest且传入

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    class MainActivity : AppCompatActivity() {
    private val workManager = WorkManager.getInstance(this)
    override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    //这里在XML中创建了一个Button,为其设置点击事件
    button.setOnClickListener {
    val wrokRequest = OneTimeWorkRequestBuilder<MyWorker>()
    .build()
    workManager.enqueue(wrokRequest)
    //将创建好的workRequest传递给workManager
    }
    }
    }

    以上,关于workManager的简单使用就完成了

WorkManager的触发条件与传递数据、串接

触发条件
1
2
3
4
5
6
 val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build()
val wrokRequest = OneTimeWorkRequestBuilder<MyWorker>()
.setConstraints(constraints)
.build()

创建一个constraints,并且给他设置触发条件为连接网络时触发,然后传递给workRequest

传递数据

可以将数据传递进Worker,Worker也可以把数据传递出来

1
2
3
4
val wrokRequest = OneTimeWorkRequestBuilder<MyWorker>()
.setConstraints(constraints)
.setInputData(workDataOf(INTPUT_WORK_KEY to data))
.build()

传递数据是通过setInputData,接受一个workData参数,workData是一个键值对,最后在Worker中接受数据

1
2
3
4
5
6
class MyWorker(context: Context, workerParams: WorkerParameters) : Worker(context, workerParams) {
override fun doWork(): Result {
val data = inputData.getString("Key")
return Result.success(workDataOf(OUT_WORK_KEY to "任务已结束"))
}
}

通过inputData 来接受数据,并且可以通过return Success来传递出去数据,在Activity/Fragment中通过LiveData观察来获取数据

1
2
3
workManage.getWorkInfoByIdLiveData(workRequestA.id).observe(this, Observer {
Toast.makeText(this, "任务完成,返回数据为${it.outputData}", Toast.LENGTH_SHORT).show()
})
串接

首先,我们先将创建触发条件与创建workRequest的内容提取出来(快捷键为:ctrl+alt+m)

1
2
3
4
5
6
7
8
9
private fun createWork(data: String): OneTimeWorkRequest {
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build()
return OneTimeWorkRequestBuilder<MyWorker>()
.setConstraints(constraints)
.setInputData(workDataOf(INTPUT_WORK_KEY to data))
.build()
}

并且给这个方法传入一个参数,用来进行与Worker之间传递数据,然后使用

1
2
3
4
5
6
7
8
private val WORK_A_DATA = "A ni shi han han"
private val WORK_B_DATA = "B ni shi han han"

val workRequestA = createWork(WORK_A_DATA)
val workRequestB = createWork(WORK_B_DATA)
workManager.beginWith(workRequestA)
.then(workRequestB)
.enqueue()

beginWith() 是传入第一个workRequest,剩下的通过then来传递,最后别忘了调用enqueue()