当前位置: 代码迷 >> 综合 >> 【JetPack-六】WorkManager学习笔记
  详细解决方案

【JetPack-六】WorkManager学习笔记

热度:23   发布时间:2023-12-15 11:08:28.0

学习视频来源:

  1. https://www.bilibili.com/video/BV1sJ41127EMlongway777
  2. 模型图来源也全截取来自该Up的视频
  3. 补充资料传送门
    在这里插入图片描述
  4. workmanager在子线程中同步执行

在这里插入图片描述

使用场景

  1. 防止后台滥用等等问题,对之前的后台任务方法进行体系化的封装
    在这里插入图片描述
  2. 工作状态信息的观察,livedata,并且workmanager是个单例
    在这里插入图片描述
  3. 添加依赖
    在这里插入图片描述
  4. 左上角的小灯,放那个红波纹上报那个提示,worker实现两参数的主构造器在这里插入图片描述

样例一:

1. 建立work类


class MyWorker(context: Context, workerParams: WorkerParameters): Worker(context, workerParams) {
    val TAG="Worker"override fun doWork(): Result {
    Log.d(TAG, "doWork: started")Thread.sleep(3000)Log.d(TAG, "doWork: finined")return Result.success()}}

2. MainAC进行调用


class MainActivity : AppCompatActivity() {
    //首先获取单例private val workManager=WorkManager.getInstance(this)override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)var binding=ActivityMainBinding.inflate(layoutInflater)setContentView(binding.root)binding.button.setOnClickListener {
    //1.内部放我们设定的这个类 创建一个工作请求val workRequest= OneTimeWorkRequestBuilder<MyWorker>().build()//2.加入队列workManager.enqueue(workRequest)}}
}
  1. 进行结果查看,ok没问题
    在这里插入图片描述

3. 引入约束条件

在这里插入图片描述

  1. 官网传送门
    在这里插入图片描述
  2. 修改MainAC,加入限定条件,断网测试

class MainActivity : AppCompatActivity() {
    //首先获取单例private val workManager=WorkManager.getInstance(this)override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)var binding=ActivityMainBinding.inflate(layoutInflater)setContentView(binding.root)binding.button.setOnClickListener {
    //3. 还可以添加约束条件val constrains=Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED)//连上网络.build()//1. 内部放我们设定的这个类 创建一个工作请求val workRequest= OneTimeWorkRequestBuilder<MyWorker>().setConstraints(constrains)//4.把设定的约束条件加进去 排入队列 有网络连接时才执行.build()//2. 加入队列workManager.enqueue(workRequest)}}
}
  1. 测试成功,断网后不执行,连点了四次。连上网后搞定运行。任务调入进去后,结束Activity,依然会执行。在最近使用将其划掉。依然可以【经过测试后发现意思是说:被后台杀死后,再次进入程序,任然会执行workmanager中的做法 推迟完成 。】
    在这里插入图片描述

3. Activity传递数据给WorkManager[键值对]

  1. MainActivity

class MainActivity : AppCompatActivity() {
    companion object{
    const val INPUT_DATA_KEY="input_data_key"const val WORK_A_NAME="Work A"}//首先获取单例private val workManager=WorkManager.getInstance(this)override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)var binding=ActivityMainBinding.inflate(layoutInflater)setContentView(binding.root)binding.button.setOnClickListener {
    //3. 还可以添加约束条件val constrains=Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED)//连上网络.build()//1. 内部放我们设定的这个类 创建一个工作请求val workRequest= OneTimeWorkRequestBuilder<MyWorker>().setConstraints(constrains)//4.把设定的约束条件加进去 排入队列 有网络连接时才执行.setInputData(workDataOf(INPUT_DATA_KEY to WORK_A_NAME))//5. 传入数据一个pairs对象 键值对.build()//2. 加入队列workManager.enqueue(workRequest)}}
}
  1. 修改worker类

class MyWorker(context: Context, workerParams: WorkerParameters): Worker(context, workerParams) {
    val TAG="Worker"override fun doWork(): Result {
    val name=inputData.getString(INPUT_DATA_KEY)Log.d(TAG, "doWork: $name started")Thread.sleep(3000)Log.d(TAG, "doWork: $name finined")return Result.success()}}
  1. 输出成功结果
    在这里插入图片描述

4. 既然可以传递进去,也可以传递出来

  1. Work类增设回调

class MyWorker(context: Context, workerParams: WorkerParameters): Worker(context, workerParams) {
    val TAG="Worker"override fun doWork(): Result {
    val name=inputData.getString(INPUT_DATA_KEY)Log.d(TAG, "doWork: $name started")Thread.sleep(3000)Log.d(TAG, "doWork: $name finined")//增设返回数据return Result.success(workDataOf(OUTPUT_DATA_KEY to "$name output"))}
}
  1. Main添加观察者模式

class MainActivity : AppCompatActivity() {
    companion object{
    const val INPUT_DATA_KEY="input_data_key"const val OUTPUT_DATA_KEY="output_data_key"const val WORK_A_NAME="Work A"}val TAG="MainAC"//首先获取单例private val workManager=WorkManager.getInstance(this)override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)var binding=ActivityMainBinding.inflate(layoutInflater)setContentView(binding.root)binding.button.setOnClickListener {
    //3. 还可以添加约束条件val constrains=Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED)//连上网络.build()//1. 内部放我们设定的这个类 创建一个工作请求val workRequest= OneTimeWorkRequestBuilder<MyWorker>().setConstraints(constrains)//4.把设定的约束条件加进去 排入队列 有网络连接时才执行.setInputData(workDataOf(INPUT_DATA_KEY to WORK_A_NAME))//5. 传入数据一个pairs对象 键值对.build()//2. 加入队列workManager.enqueue(workRequest)//6. 添加workmanager观察机制 通过请求自带的idworkManager.getWorkInfoByIdLiveData(workRequest.id).observe(this, Observer {
    Log.d(TAG, "onCreate: $it.state")//会依次有ENQUEUED RUNNING SUCCEEDED三种状态if (it.state == WorkInfo.State.SUCCEEDED) {
    Log.d(TAG, "onCreate: ${
      it.outputData.getString(OUTPUT_DATA_KEY)}")}})}}
}
  1. 观察成功
    在这里插入图片描述

5. 工作的可串接性----sharepreference测试存活

  1. 抽取约束与请求方法 传入键值对名
  2. 以sharepreference做测试
    MainAC
  3. 测试发现重启任然没问题,倘若某个work执行到一半,再次启动后会这个work的start开始执行

//9. 牛逼 给sharedpreference写监听器
class MainActivity : AppCompatActivity(),SharedPreferences.OnSharedPreferenceChangeListener {
    companion object{
    const val INPUT_DATA_KEY="input_data_key"const val OUTPUT_DATA_KEY="output_data_key"const val WORK_A_NAME="Work A"const val WORK_B_NAME="Work B"const val SHARED_PREFERENCES_NAME="shp_name"}val TAG="MainAC"//首先获取单例private val workManager=WorkManager.getInstance(this)val binding by lazy {
     ActivityMainBinding.inflate(layoutInflater) }override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)setContentView(binding.root)val sp=getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE)sp.registerOnSharedPreferenceChangeListener(this)updateView()binding.button.setOnClickListener {
    val workRequestA = createWork(WORK_A_NAME)val workRequestB = createWork(WORK_B_NAME)//2. 加入队列//8. 变更添加方式
// workManager.enqueue(workRequest) 先完成A,再执行BworkManager.beginWith(workRequestA).then(workRequestB).enqueue()//6. 添加workmanager观察机制 通过请求自带的id
// workManager.getWorkInfoByIdLiveData(workRequest.id).observe(this, Observer {
    
// Log.d(TAG, "onCreate: $it.state")//会依次有ENQUEUED RUNNING SUCCEEDED三种状态
// if (it.state == WorkInfo.State.SUCCEEDED) {
    
// Log.d(TAG, "onCreate: ${it.outputData.getString(OUTPUT_DATA_KEY)}")
// }
// })}}//刷新两个textviewprivate fun updateView(){
    val sp=getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE)binding.textViewA.text=sp.getInt(WORK_A_NAME,0).toString()binding.textViewB.text=sp.getInt(WORK_B_NAME,0).toString()}//7. 抽取约束与请求方法,传入键值对的值名-对应不同工作private fun createWork(name:String): OneTimeWorkRequest {
    //3. 还可以添加约束条件val constrains = Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED)//连上网络.build()//1. 内部放我们设定的这个类 创建一个工作请求val workRequest = OneTimeWorkRequestBuilder<MyWorker>().setConstraints(constrains)//4.把设定的约束条件加进去 排入队列 有网络连接时才执行.setInputData(workDataOf(INPUT_DATA_KEY to name))//5. 传入数据一个pairs对象 键值对.build()return workRequest}//实现回调方法override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {
    updateView()}
}

MyWorker


class MyWorker(context: Context, workerParams: WorkerParameters): Worker(context, workerParams) {
    val TAG="Worker"override fun doWork(): Result {
    val name=inputData.getString(INPUT_DATA_KEY)Log.d(TAG, "doWork: $name started")Thread.sleep(6000)//以传递过来的name作为key的nameval sp=applicationContext.getSharedPreferences(SHARED_PREFERENCES_NAME,Context.MODE_PRIVATE)var number=sp.getInt(name,0)sp.edit().putInt(name,++number).apply()Log.d(TAG, "doWork: $name finined")//增设返回数据return Result.success(workDataOf(OUTPUT_DATA_KEY to "$name output"))}
}