安卓系列之 Jetpack 架构(AAC):WorkManager 基础篇

356 阅读3分钟

适用场景

任务无需立马执行,或者任务可以在 APP 退出之后执行。

运用实例

  1. 定期向服务器上传 APP 日志
  2. 定时同步服务端信息

优点

  1. 优化了电池续航问题
  2. 工作约束可以明确定义工作运行的最佳条件
  3. 灵活的重试政策和指数退避政策
  4. 工作链,可处理多任务且不同顺序执行

引用

dependencies {
    def work_version = "2.5.0"

    // (Java only)
    implementation "androidx.work:work-runtime:$work_version"

    // Kotlin + coroutines
    implementation "androidx.work:work-runtime-ktx:$work_version"

    // optional - RxJava2 support
    implementation "androidx.work:work-rxjava2:$work_version"

    // optional - GCMNetworkManager support
    implementation "androidx.work:work-gcm:$work_version"

    // optional - Test helpers
    androidTestImplementation "androidx.work:work-testing:$work_version"

    // optional - Multiprocess support
    implementation "androidx.work:work-multiprocess:$work_version"
}

简单实例

Build.gradle

在 dependencies 中引入 workmanager

//workManager
implementation "androidx.work:work-runtime:2.5.0"

LogWork

继承 Worker,重写 doWork()方法,根据情况返回对应 result 的值。

package com.elaine.testworkmanager;

import android.content.Context;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.work.Worker;
import androidx.work.WorkerParameters;

/**
 * 日志任务
 * author: elaine
 * date: 2021/7/14
 */
public class LogWork extends Worker {

    public LogWork(@NonNull Context context, @NonNull WorkerParameters workerParams) {
        super(context, workerParams);
    }

    @NonNull
    @Override
    public Result doWork() {
        Log.e("doWork", "日志任务执行了");
        return Result.success();
    }
}

MainActivity


import android.os.Bundle;

import androidx.appcompat.app.AppCompatActivity;
import androidx.work.Constraints;
import androidx.work.NetworkType;
import androidx.work.OneTimeWorkRequest;
import androidx.work.WorkManager;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        startLogWork();
    }

    private void startLogWork() {
        //设置触发条件
        Constraints constraints = new Constraints.Builder()
                //对网络没有要求
                .setRequiredNetworkType(NetworkType.NOT_REQUIRED)
                .build();

        //单次工作请求
        OneTimeWorkRequest oneTimeWorkRequest = new OneTimeWorkRequest.Builder(LogWork.class)
                //设置触发条件
                .setConstraints(constraints)
                .build();
        //任务manager
        WorkManager.getInstance(this).enqueue(oneTimeWorkRequest);
    }
}

运行结果

Worker

自定义工作,继承 Worker,增加构造方法,重写 doWork()方法。

返回值意义
Result.success()工作成功完成
Result.failure()工作失败
Result.success(Data)工作成功完成并传递数据
Result.failure(Data)工作失败并传递数据
Result.retry()工作失败,应根据其重试政策在其他时间尝试
在 doWork 方法中获取数据
@NonNull
@Override
public Result doWork() {
    //获取数据
    String inputData = getInputData().getString("input_data");
    Log.d("inputData",inputData);
    //任务执行完之后,返回数据
    Data outputData = new Data.Builder()
            .putString("output_data", "执行成功")
            .build();
     return Result.success(outputData);
}

Constraints

用于配置触发条件,即工作约束。

Constraints constraints = new Constraints.Builder()
                //.setRequiresBatteryNotLow(true) //电量不足不执行
                //.setRequiresCharging(true) //在充电时执行
                //.setRequiresStorageNotLow(true) //存储容量不足时不执行
                //.setRequiresDeviceIdle(true) //在待机状态下执行 调用需要API级别最低为23
                //.setRequiredNetworkType(NetworkType.NOT_REQUIRED)
                // NetworkType.NOT_REQUIRED:对网络没有要求
                // NetworkType.CONNECTED:网络连接时执行
                // NetworkType.UNMETERED:不计费的网络比如WIFI下执行
                // NetworkType.NOT_ROAMING:非漫游网络状态执行
                // NetworkType.METERED:计费网络比如3G,4G下执行
                .build();

WorkRequest

定义工作运行方式和时间。

  1. 设置触发条件
//设置触发条件
.setConstraints(constraints)
  1. 延迟执行
//设置延迟执行
.setInitialDelay(5, TimeUnit.SECONDS)
  1. 退避政策
    LINEAR----重试间隔都会增加约 10 秒,例如:20 秒、30 秒、40 秒
    EXPONENTIAL----指数级增加时间间隔,例如:20 秒、40 秒、80 秒
//指数退避策略
.setBackoffCriteria(BackoffPolicy.LINEAR, Duration.ofSeconds(10))
  1. 标记工作
    方便取消工作或者观察工作。
//设置tag标签
.addTag("workRequest")
  1. 传递参数
Data inputData = new Data.Builder()
        .putString("input_data","data")
        .build();

//参数传递
.setInputData(inputData)

子类 OneTimeWorkRequest

调用一次性工作

WorkRequest uploadWorkRequest =
   new OneTimeWorkRequest.Builder(MyWork.class)
       // Additional configuration
       .build();

子类 PeriodicWorkRequest

调度定期工作
注意:可以定义的最短重复间隔是 15 分钟

PeriodicWorkRequest saveRequest =
       new PeriodicWorkRequest.Builder(SaveImageToFileWorker.class, 1, TimeUnit.HOURS)
           // Additional configuration
           .build();

WorkManager

任务管理器

  1. 新增工作
WorkManager.getInstance(this).enqueue(workRequest);
  1. 取消工作
WorkManager.getInstance(this).cancelWorkById(workRequest.getId());
  1. 观察工作
WorkManager.getInstance(this).getWorkInfoByIdLiveData(workRequest.getId()).observe(this, new Observer<WorkInfo>() {
    @Override
    public void onChanged(WorkInfo workInfo) {
       Log.d("WorkInfo",workInfo.toString());
    }
});

链接工作

多个工作按照一定的顺序执行。

WorkManager.getInstance(myContext)
   // Candidates to run in parallel
   .beginWith(Arrays.asList(plantName1, plantName2, plantName3))
   // Dependent work (only runs after all previous work in chain)
   .then(cache)
   .then(upload)
   // Call enqueue to kick things off
   .enqueue();

项目 github 地址

github.com/ElaineTaylo…

若帅哥美女对该系列文章感兴趣,可微信搜索公众号(木子闲集)关注更多更新文章哦,谢谢~