Android可保活的、不依附于应用进程存活的后台任务框架:WorkManager

WorkManager旨在实现不依附与App进程的后台线程化任务。举例来说,假设App在本地有一个大小约2GB的文件需要上传到远程服务器。App希望在手机空闲且设备资源充足的情况下将这2GB大小的文件上传。
同时,该上传任务不受App进程存活与否影响(比如当前App进程被kill掉,仍能执行该任务)。这种类型的后台任务明显区别于过往的依附于App进程的Thread线程池一类的耗时任务。WorkManager实现的,是独立的、不依附于App进程的真正的后台耗时任务。
在过往,常规实现的Android后台任务(service,线程等),很容易受到寄宿的App进程情况影响,影响主要来自于无法保证寄宿的App进程一定存活。

import android.os.Bundle;import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer;
import androidx.work.Constraints;
import androidx.work.Data;
import androidx.work.NetworkType;
import androidx.work.OneTimeWorkRequest;
import androidx.work.WorkInfo;
import androidx.work.WorkManager;import java.util.Arrays;
import java.util.List;public class MainActivity extends AppCompatActivity {static final String TIME = "time";static final String DATA = "data";static final String ID = "id";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);test();}private void test() {String TAG = "tag";OneTimeWorkRequest a = getRequest(TAG, 1000, "A", TestWorker.class);OneTimeWorkRequest b = getRequest(TAG, 2000, "B", TestWorker.class);OneTimeWorkRequest c = getRequest(TAG, 3000, "C", TestWorker.class);OneTimeWorkRequest d = getRequest(TAG, 4000, "D", TestWorker.class);WorkManager.getInstance(this).enqueue(Arrays.asList(a, b, c, d));LiveData<List<WorkInfo>> liveData = WorkManager.getInstance(this).getWorkInfosByTagLiveData(TAG);liveData.observe(this, new Observer<List<WorkInfo>>() {@Overridepublic void onChanged(List<WorkInfo> workInfos) {System.out.println("长度:" + workInfos.size());for (WorkInfo info : workInfos) {if (info.getState() == WorkInfo.State.SUCCEEDED) {Data data = info.getOutputData();String s = data.getString(DATA);Long time = data.getLong(TIME, -1);String id = data.getString(ID);System.out.println("onChanged:" + id + " " + s + " " + time);}}}});System.out.println("UI Main线程Id:" + Thread.currentThread().getId());//取消任务。//UUID workId = workRequest.getId();//WorkManager.getInstance().cancelByWorkId(workId);}private OneTimeWorkRequest getRequest(String tag, int time, String id, Class cls) {//传递的参数数据。Data data = new Data.Builder().putInt(TIME, time).putString(ID, id).putString(DATA, "phil " + id).build();Constraints constraints = new Constraints.Builder()//触发规则。.setRequiresStorageNotLow(false).setRequiresBatteryNotLow(false).setRequiresCharging(false).setRequiredNetworkType(NetworkType.NOT_REQUIRED)//对络连接不做要求。.build();OneTimeWorkRequest request = new OneTimeWorkRequest.Builder(cls).setInputData(data).setConstraints(constraints).addTag(tag).build();return request;}
}
package zhangphil.demo;import android.content.Context;
import android.os.SystemClock;import androidx.annotation.NonNull;
import androidx.work.Data;
import androidx.work.Worker;
import androidx.work.WorkerParameters;public class TestWorker extends Worker {private String id;private int time;public TestWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {super(context, workerParams);Data data = workerParams.getInputData();time = data.getInt(MainActivity.TIME, -1);id = data.getString(MainActivity.ID);String content = data.getString(MainActivity.DATA);System.out.println("Worker:传入数据->id:" + id + " time:" + time + " data:" + content);}/*** doWork()函数体已经线程化。** @return*/@NonNull@Overridepublic Result doWork() {//模拟耗时操作。SystemClock.sleep(time);System.out.println("doWork:" + id + "-线程Id:" + Thread.currentThread().getId() + " 完成");//传输数据给外部监听者。Data data = new Data.Builder().putString(MainActivity.ID, id).putString(MainActivity.DATA, "数据回传").putLong(MainActivity.TIME, System.currentTimeMillis()).build();return Result.success(data);}@Overridepublic void onStopped() {super.onStopped();}
}

输出:

15477-15477/? I/System.out: UI Main线程Id:2
15477-15498/? I/System.out: Worker:传入数据->id:A time:1000 data:phil A
15477-15496/? I/System.out: Worker:传入数据->id:B time:2000 data:phil B
15477-15498/? I/System.out: Worker:传入数据->id:C time:3000 data:phil C
15477-15493/? I/System.out: Worker:传入数据->id:D time:4000 data:phil D
15477-15477/? I/System.out: 长度:4
15477-15477/? I/System.out: 长度:4
15477-15502/zhangphil.app I/System.out: doWork:A-线程Id:609 完成
15477-15477/zhangphil.app I/System.out: 长度:4
15477-15477/zhangphil.app I/System.out: onChanged:A 数据回传 1561542140123
15477-15503/zhangphil.app I/System.out: doWork:B-线程Id:610 完成
15477-15477/zhangphil.app I/System.out: 长度:4
15477-15477/zhangphil.app I/System.out: onChanged:B 数据回传 1561542141126
15477-15477/zhangphil.app I/System.out: onChanged:A 数据回传 1561542140123
15477-15505/zhangphil.app I/System.out: doWork:C-线程Id:611 完成
15477-15477/zhangphil.app I/System.out: 长度:4
15477-15477/zhangphil.app I/System.out: onChanged:C 数据回传 1561542142127
15477-15477/zhangphil.app I/System.out: onChanged:B 数据回传 1561542141126
15477-15477/zhangphil.app I/System.out: onChanged:A 数据回传 1561542140123
15477-15502/zhangphil.app I/System.out: doWork:D-线程Id:609 完成
15477-15477/zhangphil.app I/System.out: 长度:4
15477-15477/zhangphil.app I/System.out: onChanged:C 数据回传 1561542142127
15477-15477/zhangphil.app I/System.out: onChanged:B 数据回传 1561542141126
15477-15477/zhangphil.app I/System.out: onChanged:A 数据回传 1561542140123
15477-15477/zhangphil.app I/System.out: onChanged:D 数据回传 1561542144125

注意:本例基于WorkManager版本 2.1.0-beta02

implementation "androidx.work:work-runtime:2.1.0-beta02"

经验证发现,如果把a,b,c,d四个任务以任务链的形式组合任务,即使用WorkManager的beginWith-then设计任务链,至少存在一个问题:
在WorkManager构建阶段,通过setInputData传递给Worker的数据只有第一个任务可以成功,后面的传递失败。
具体原因不明,可能是Android官方还没有形成稳定的正式版。

附:

《Android体系架构:WorkManager》https://zhangphil.blog.csdn.net/article/details/89399972

Android可保活的、不依附于应用进程存活的后台任务框架:WorkManager相关推荐

  1. 【Android 进程保活】应用进程拉活 ( 双进程守护 + JobScheduler 保活 | 成功率最高 | 推荐使用 )

    文章目录 一. 双进程守护保活 + JobScheduler 原理 二. 双进程守护保活 + JobScheduler 源码 1.JobService 代码 2.判定服务运行工具类 3.清单文件 4. ...

  2. 【Android 进程保活】应用进程拉活 ( 账户同步拉活 | 账号添加 | 源码资源 )

    文章目录 一. 账号添加 二. 代码示例 1. 账号添加工具类 2. 权限注册 3. 在 Activity 中调用上述工具类 4. 运行效果 三. 源码资源 一. 账号添加 在上一篇博客 [Andro ...

  3. 【Android 进程保活】提升进程优先级 ( 使用前台 Service 提高应用进程优先级 | 启动相同 id 的第二个前台 Service 关闭通知 )

    文章目录 一. 前台 Service 通知问题 二. 设置 startForeground id 参数为 0 三. 启动相同 id 的第二个前台 Service 关闭通知 1. 前台服务 1 2. 关 ...

  4. 【Android 进程保活】提升进程优先级 ( 使用前台 Service 提高应用进程优先级 | 效果展示 | 源码资源 )

    文章目录 一. 使用前台 Service 提高应用进程优先级 1. 前台 Service 代码 2. 前台 Service 代码 3. 启动服务 二.效果展示 三.源码资源 一. 使用前台 Servi ...

  5. 【Android 进程保活】应用进程拉活 ( 双进程守护保活 )

    文章目录 一. 双进程守护保活原理 二. 双进程守护保活完整源码 1.AIDL 接口 2.本地前台服务 Service 3.远程前台服务 Service 4.清单配置 5.启动两个服务 5.执行效果 ...

  6. Android进程保活

    Android进程回收机制 Low Memory Killer原理 微信团队原创分享:Android版微信后台保活实战分享(网络保活篇) 微信团队原创分享:Android版微信后台保活实战分享(进程保 ...

  7. Android 系统(265)----Android进程保活全攻略(上)

    Android进程保活全攻略(上) 对于每个公司的APP来说,当然都希望自己APP的进程尽量的不被杀死,于是乎,就有了一些列进程保活的方法出现,网上也有很多关于这类的文章,但网上很多资料往往只告诉了思 ...

  8. Android 系统(146)----Android进程保活招数概览

    Android进程保活招数概览 Android中的进程保活应该分为两个方面: 提高进程的优先级,减少被系统杀死的可能性 在进程已经被杀死的情况下,通过一些手段来重新启动应用进程 本文针对这两方面来进程 ...

  9. Android进程保活的一般套路

    自己曾经也在这个问题上伤过脑经,前几日刚好有一个北京的哥们在QQ说在做IM类的项目,问我进程保活如何处理比较恰当,决定去总结一下,网上搜索一下进程常驻的方案好多好多,但是很多的方案都是不靠谱的或者不是 ...

  10. 【腾讯Bugly干货分享】Android进程保活招式大全

    [腾讯Bugly干货分享]Android进程保活招式大全 本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57ac4a0ea374 ...

最新文章

  1. monocross 环境搭建:MonoTouch Mono for Android
  2. javascript 高级程序设计_JavaScript 经典「红宝书」,几代前端人的入门选择
  3. 物联网智能硬件设备身份验证机制
  4. 解决 js ajax跨域访问报“No 'Access-Control-Allow-Origin' header is present on the requested resource.”错误
  5. linux主从库配置文件,linux 数据库主从同步配置
  6. 非root用户ssh 执行 sudo远程机器免密钥
  7. 数据结构-树的进阶代码
  8. 一点感想——还没学会跑,怎么能够想着飞
  9. 从ajax获取的数据无法通过Jquery选择器来调用事件
  10. winform 更新服务器程序
  11. Docker第二章:搭建CentOS+JDK+Tomcat环境
  12. java贪吃蛇总结报告_java贪吃蛇开发总结
  13. 初中毕业学修车还是学计算机,儿子初中毕业了,成绩不好,想学门手艺谋生,去技校,还是去店里做学徒好?学修车吗?...
  14. python 函数注释出现 :expected an indented block
  15. winform控件焦点设置
  16. linux glib,我该如何安装glib?
  17. 计算广告第四章——合约广告
  18. java开发平台有哪些_java都有哪些开发平台
  19. 新版Chrome自动禁用第三方插件的解决办法[转]
  20. JZOJ2020年8月11日提高组T3 页

热门文章

  1. 【10】C++之泛型算法
  2. 数电学习(五、触发器)(一)
  3. “持咒”到底是个什么东西?----再论语言和思维关系
  4. Git是什么?如何安装Git?
  5. 网络安全--防火墙旁挂部署方式和高可靠性技术
  6. thinkphp6.0 EXCEL表格导出
  7. 一文读懂docker
  8. LeetCode10-正则表达式匹配
  9. 大学天坑专业自学网络安全,半年才找到工作,非万不得已,劝你还是不要学...
  10. “九韶杯”[友谊纽带] 喊山 (30 分) 小字辈 bfs,dfs求距离