Android--Jetpack--WorkManager详解
编程语言的未来?
目录
一,定义
WorkManager是Android Jetpack的一部分,开发中,我们的任务不可能总是在前台,但是还要确保那些重要任务的执行,我们就可以放置 在后台执行,那么WorkManager就能够发挥其作用了。 它适用于需要保证系统即使应用程序退出也会运行的任务,WorkManager API可以轻松指定可延迟的 异步任务以及何时运行它们,这些API允许您创建任务并将其交给WorkManager立 即运行或在适当的时间运行。 WorkManager根据设备API级别和应用程序状态等因素选择适当的方式来运行任 务。如果WorkManager在应用程序运行时执行您的任务之一,WorkManager可以 在您应用程序进程的新线程中运行您的任务。如果您的应用程序未运行, WorkManager会选择一种合适的方式来安排后台任务 - 具体取决于设备API级别和包 含的依赖项,WorkManager可能会使用 JobScheduler,Firebase JobDispatcher或 AlarmManager
二,特点
1,支持异步一次性和定期任务
2,支持网络条件,存储空间和充电状态等约束
3,链接复杂的工作请求,包括并行运行工作
4,一个工作请求的输出用作下一个工作的输入
5,将API级别的兼容性处理回API级别14(请参阅注释)
6,可以使用或不使用Google Play服务
7,遵循系统健康最佳实践
8,LiveData支持可轻松在UI中显示工作请求状态
三,作用
1,确保重要的后台任务,一定会被执行,后台任务(例如:非及时性的 (请求服 务器 及时性) 上传,下载,同步数据 等)
2,内部对电量进行了优化,不需要我们去处理电量优化了
3,API 14 到 最新版本,都可以使用WorkManager来管你你的后台任务
4,注意:WorkManager不能做保活操作
5,调度,管理,执行的后台任务的场景,通常是是可延迟的后台任务
四,角色
1,Worker:指定需要执行的任务,可以成为Workder类的子类,在实现的方法中,就可以执行任务逻辑了
2,WorkRequest:执行一项单一的任务
①:WorkRequest对象必须指定Work执行的任务
②:WorkRequest都有一个自动生成的唯一ID,可以使用ID执行取消 排队任务 或 获取任务状态等操作
③:WorkRequest是一个抽象的类;系统默认实现子类 OneTimeWorkRequest或PeriodicWorkRequest
④:WorkRequest.Builder创建WorkRequest对象;相应的子类: OneTimeWorkRequest.Builder或PeriodicWorkRequest.Builder
⑤:Constraints:指定对任务运行时间的限制(任务约束);使用 Constraints.Builder创建Constraints对象 ,并传递给WorkRequest.Builder
3,WorkManager:排队和管理工作请求;将WorkRequest 对象传递WorkManager的 任务队列
(注意:如果未指定任何约束, WorkManager立即运行任务)
4,WorkStatus:包含有关特定任务的信息;可以使用LiveData保存 WorkStatus对象, 监听任务状态;如LiveData
五,简单使用
1,添加依赖
implementation "androidx.work:work-runtime:2.7.1"
2,创建自己的worler并继承worker
public class YZWorker1 extends Worker {
public YZWorker1(@NonNull Context context, @NonNull WorkerParameters workerParams) {
super(context, workerParams);
}
//后台执行的任务 并且是异步的
@NonNull
@Override
public Result doWork() {
System.out.println("YZWorker1:执行后台任务");
//成功就返回success 失败返回failure
return Result.success();
}
}
3,在activity中使用
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical">
<TextView
android:id="@+id/txt_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="YZWorker1"
/>
</LinearLayout>
public class MainActivity extends AppCompatActivity {
private TextView txt1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txt1 = findViewById(R.id.txt_1);
txt1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
OneTimeWorkRequest oneTimeWorkRequest =
new OneTimeWorkRequest.Builder(YZWorker1.class).build();
WorkManager.getInstance(MainActivity.this).enqueue(oneTimeWorkRequest);
}
});
}
}
4,点击按钮输出如下
?
?六,数据传递
实现activity和worker的数据传递:
1,创建worker
public class YZWorker2 extends Worker {
private Context mContext;
private WorkerParameters workerParams;
public YZWorker2(@NonNull Context context, @NonNull WorkerParameters workerParams) {
super(context, workerParams);
this.mContext = context;
this.workerParams = workerParams;
}
@SuppressLint("RestrictedApi")
@NonNull
@Override
public Result doWork() {
// 接收 MainActivity传递过来的数据
String data = workerParams.getInputData().getString("YuanZhen");
System.out.println("YZWorker2:Activity传递过来的数据:"+data);
// 把任务中的数据回传到activity中
Data outputData = new Data.Builder().putString("YuanZhen", "我是worker2的数据").build();
Result.Success success = new Result.Success(outputData);
return success;
}
}
2,在activity中使用
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical">
<TextView
android:id="@+id/txt_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="YZWorker1"
/>
<TextView
android:id="@+id/txt_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="YZWorker2"
/>
</LinearLayout>
public class MainActivity extends AppCompatActivity {
private TextView txt2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txt2 =findViewById(R.id.txt_2);
txt2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// 数据
Data sendData = new Data.Builder().putString("YuanZhen", "我是MainActivity的数据").build();
// 请求对象初始化
OneTimeWorkRequest oneTimeWorkRequest = new OneTimeWorkRequest.Builder(YZWorker2.class)
.setInputData(sendData)
.build();
// 想接收任务回馈的数据,需要状态机
WorkManager.getInstance(MainActivity.this).getWorkInfoByIdLiveData(oneTimeWorkRequest.getId())
.observe(MainActivity.this, workInfo -> {
System.out.println("MainActivity:当前状态:"+workInfo.getState().name());
if (workInfo.getState().isFinished()) {
// 状态机 成功的时候 才去打印
System.out.println("MainActivity:取到了任务回传的数据:"+workInfo.getOutputData().getString("YuanZhen"));
}
});
WorkManager.getInstance(MainActivity.this).enqueue(oneTimeWorkRequest);
}
});
}
}
3,点击按钮输出如下
?
?七,多个任务顺序执行
1,创建三个worker
public class YZWorker3 extends Worker {
public YZWorker3(@NonNull Context context, @NonNull WorkerParameters workerParams) {
super(context, workerParams);
}
@NonNull
@Override
public Result doWork() {
System.out.println("YZWorker3:执行了");
return Result.success();
}
}
public class YZWorker4 extends Worker {
public YZWorker4(@NonNull Context context, @NonNull WorkerParameters workerParams) {
super(context, workerParams);
}
@NonNull
@Override
public Result doWork() {
System.out.println("YZWorker4:执行了");
return Result.success();
}
}
public class YZWorker5 extends Worker {
public YZWorker5(@NonNull Context context, @NonNull WorkerParameters workerParams) {
super(context, workerParams);
}
@NonNull
@Override
public Result doWork() {
System.out.println("YZWorker5:执行了");
return Result.success();
}
}
2,在activity中使用
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical">
<TextView
android:id="@+id/txt_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="YZWorker1"
/>
<TextView
android:id="@+id/txt_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="YZWorker2"
/>
<TextView
android:id="@+id/txt_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="YZWorker3"
/>
</LinearLayout>
public class MainActivity extends AppCompatActivity {
private TextView txt3;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txt3 =findViewById(R.id.txt_3);
txt3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// 单一的任务 一次
OneTimeWorkRequest oneTimeWorkRequest3 = new OneTimeWorkRequest.Builder(YZWorker3.class).build();
OneTimeWorkRequest oneTimeWorkRequest4 = new OneTimeWorkRequest.Builder(YZWorker4.class).build();
OneTimeWorkRequest oneTimeWorkRequest5 = new OneTimeWorkRequest.Builder(YZWorker5.class).build();
// 顺序执行 3 4 5
WorkManager.getInstance(MainActivity.this)
.beginWith(oneTimeWorkRequest3)
.then(oneTimeWorkRequest4)
.then(oneTimeWorkRequest5)
.enqueue();
}
});
}
}
3,点击按钮输出如下
八,重复执行后台任务
public class MainActivity extends AppCompatActivity {
private TextView txt4;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txt4 =findViewById(R.id.txt_4);
txt4.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// 不能小于15分钟,否则默认修改成 15分钟
PeriodicWorkRequest periodicWorkRequest
= new PeriodicWorkRequest.Builder(YZWorker5.class, 10, TimeUnit.SECONDS).build();
// 一直都是 ENQUEUE,因为是轮询的任务,所以看不到 SUCCESS 如果是单个任务,就会看到SUCCESS
WorkManager.getInstance(MainActivity.this).getWorkInfoByIdLiveData(periodicWorkRequest.getId())
.observe(MainActivity.this, new Observer<WorkInfo>() {
@Override
public void onChanged(WorkInfo workInfo) {
System.out.println("MainAcitvity状态:"+workInfo.getState().name());
if (workInfo.getState().isFinished()) {
System.out.println("MainAcitvity状态:isFinished=true");
}
}
});
WorkManager.getInstance(MainActivity.this).enqueue(periodicWorkRequest);
}
});
}
}
九,添加约束条件
public class MainActivity extends AppCompatActivity {
private TextView txt5;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txt5 =findViewById(R.id.txt_5);
txt5.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// 约束条件,必须满足条件,才能执行后台任务
Constraints constraints = new Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED) // 网络连接
.setRequiresCharging(true) // 充电
.build();
OneTimeWorkRequest request = new OneTimeWorkRequest.Builder(YZWorker3.class)
.setConstraints(constraints)
.build();
// 加入队列
WorkManager.getInstance(MainActivity.this).enqueue(request);
}
});
}
}
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!