Android-Jetpack笔记--WorkManager

         这一节来熟悉一下Jetpack后台执行任务库WorkManager,由于很多Android应用程序都有在后台执行任务的需求,目前Android为后台任务提供了多种解决方案,如JobScheduler,Loader,Service等,如果这些API没有被适当地使用,可能会消耗大量的电量。Android在解决应用程序耗电问题上做了各种尝试,从Doze到App Standby,通过各种方式限制和管理应用程序,以保证应用程序不会在后台过量消耗设备电量。WorkManager的出现,则是为应用程序中那些不需要及时完成的任务,提供统一的解决方案,以便在设备电量和用户体验之间达到一个比较好的平衡。

        WorkManager 提供一种任务调度功能,可以对任务进行标记或命名。用法如下:

Worker定义:

class CompressingWorker(context: Context,params:WorkerParameters) : Worker(context,params) {

    override fun doWork(): Result {
        try {

            for (i in 0 ..300) {
                Log.i("Worker", "Compressing $i")
            }

            return Result.success()
        } catch (e:Exception){
            return Result.failure()
        }
    }
}
class DownloadingWorker(context: Context,params:WorkerParameters) : Worker(context,params) {

    override fun doWork(): Result {
        try {

            for (i in 0 ..3000) {
                Log.i("Worker", "Downloading $i")
            }
            val time = SimpleDateFormat("dd/M/yyyy hh:mm:ss")
            val currentDate = time.format(Date())
            Log.i("MYTAG","Completed $currentDate")
            return Result.success()
        } catch (e:Exception){
            return Result.failure()
        }
    }
}

class FilteringWorker(context: Context,params:WorkerParameters) : Worker(context,params) {
    override fun doWork(): Result {
        try {

            for (i in 0 ..3000) {
                Log.i("Worker", "Filtering $i")
            }

            return Result.success()
        } catch (e:Exception){
            return Result.failure()
        }
    }
}
class UploadWorker(context: Context,params:WorkerParameters) : Worker(context,params) {

    companion object{
        const val KEY_WORKER = "key_worker"
    }

    override fun doWork(): Result {
        try {
            val count = inputData.getInt(MainActivity.KEY_COUNT_VALUE,0)
            for (i in 0 until count) {
                Log.i("Worker", "Uploading $i")
            }

            val time = SimpleDateFormat("dd/M/yyyy hh:mm:ss")
            val currentDate = time.format(Date())

            val outPutData = Data.Builder()
                .putString(KEY_WORKER,currentDate)
                .build()

            return Result.success(outPutData)
        } catch (e:Exception){
            return Result.failure()
        }
    }
}

class MainActivity : AppCompatActivity() {

    companion object{
    const val KEY_COUNT_VALUE = "key_count"
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        button.setOnClickListener {
            setOneTimeWorkRequest()
//            setPeriodicWorkRequest()
        }
    }

    private fun setOneTimeWorkRequest() {
        // 一次性任务 一旦执行完就自动结束
        val workManager = WorkManager.getInstance(applicationContext)

        val data: Data = Data.Builder()
            .putInt(KEY_COUNT_VALUE,125)
            .build()
        val constraints = Constraints.Builder()
            .setRequiresCharging(true)
            .setRequiredNetworkType(NetworkType.CONNECTED)
            .build()

        val uploadRequest = OneTimeWorkRequest.Builder(UploadWorker::class.java)
            .setConstraints(constraints)
            .setInputData(data)
            .build()

        val filteringRequest = OneTimeWorkRequest.Builder(FilteringWorker::class.java)
            .build()
        val compressingRequest= OneTimeWorkRequest.Builder(CompressingWorker::class.java)
            .build()
        val downloadingWorker= OneTimeWorkRequest.Builder(DownloadingWorker::class.java)
            .build()
        val paralleWorks = mutableListOf<OneTimeWorkRequest>()
        paralleWorks.add(downloadingWorker)
        paralleWorks.add(filteringRequest)
        workManager
            .beginWith(paralleWorks)
            .then(compressingRequest)
            .then(uploadRequest)
            .enqueue()

        workManager.getWorkInfoByIdLiveData(uploadRequest.id)
            .observe(this, Observer {
                textView.text = it.state.name
                if(it.state.isFinished){
                 val data = it.outputData
                 val message = data.getString(UploadWorker.KEY_WORKER)
                    Toast.makeText(applicationContext,message,Toast.LENGTH_LONG).show()
                }
            })
    }

    private fun setPeriodicWorkRequest(){
   // 周期性任务  最少间隔15分钟
       val periodicWorkRequest = PeriodicWorkRequest
           .Builder(DownloadingWorker::class.java,16,TimeUnit.MINUTES)
           .build()
      WorkManager.getInstance(applicationContext).enqueue(periodicWorkRequest)
    }
}
 为任务设置Tag标签。设置Tag后,你就可以通过该标签跟踪任务的状态WorkManager.getWorkInfosByTagLiveData(String tag)或者取消任务WorkManager.cancelAllWorkByTag(String tag)。    

           WorkManager最低能兼容API Level 14,并不需要你的设备安装有Google Play Services。它的两个重要特点: 1.针对不需要及时完成的任务 比如,发送应用程序日志,同步应用程序数据,备份用户数据等。站在业务的角度,这些任务都不需要立即完成,如果我们自己来管理这些任务,逻辑可能会非常复杂,若API使用不恰当,可能会消耗大量电量。2.保证任务一定会被执行,WorkManager能保证任务一定会被执行,即使你的应用程序当前不在运行中,怕你的应用程序彻底退出,或者设备重新启动,WorkManager依然能够保证完成你交给的任务。因为WorkManager有自己的数据库,关于任务的所有信息和数据都保存在这个数据库中,注意:WorkManager不是一种新的工作线程,它的出现不是为了替代其它类型的工作线程。工作线程通常立即运行,并在执行完成后给到用户反馈。而WorkManager不是即时的,它不能保证任务能立即得到执行。

猜你喜欢

转载自blog.csdn.net/ljt2724960661/article/details/121058810