iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >Android开发之定时任务(AlarmManager、WorkManager)
  • 546
分享到

Android开发之定时任务(AlarmManager、WorkManager)

androidjava开发语言 2023-08-18 05:08:03 546人浏览 泡泡鱼
摘要

Android 程序的定时任务主要有AlarmManager、WorkManager两种。 一、AlarmManager AlarmManager,又称闹钟,可以设置一次性任务,周期重复任务,定时重复任务。 AlarmManager 通过

Android 程序的定时任务主要有AlarmManager、WorkManager两种。

一、AlarmManager

AlarmManager,又称闹钟,可以设置一次性任务,周期重复任务,定时重复任务。
AlarmManager 通过 PendingIntent 传递要执行的任务程序,可以是广播、跳转页面、后台服务、前台服务等。

1、PendingIntent介绍

本节参考文章:https://zhuanlan.zhihu.com/p/544564416

PendingIntent 是一种延迟的 Intent,表示一种延迟执行的意图操作。
PendingIntent 一种是支持授权其他应用以当前应用的身份执行包装的 Intent 操作的系统特性。
从结构上来说,PendingIntent 是 Intent 的包装类

使用代码示例:

 Intent intent = new Intent(this, MyIntentService.class); PendingIntent serviceIntent = PendingIntent.getService(this, requestCode, intent,PendingIntent.FLAG_UPDATE_CURRENT| PendingIntentPendingIntent.FLAG_IMMUTABLE);

PendingIntent通过如下方法获取各种场景实例:

  • PendingIntent.getBroadcast(),广播,类似 Context.sendBroadcast(),Intent对应的class必须是BroadcastReceiver子类
  • PendingIntent.getActivity(),跳转活动页面,类似 Context.startActivity(Intent),Intent对应的class必须是一个Activity
  • PendingIntent.getService(),后台服务,类似 Context.startService(),Intent对应的class必须是Service子类
  • PendingIntent.getForegroundService(),前台服务,类似 Context.startForegroundService()

简单说明下创建 PendingIntent 的 4 个参数:

context: 当前应用的上下文,PendingIntent 将从中抽取授权信息;
2、requestCode: PendingIntent 的请求码,与 Intent 的请求码类似;
3、intent: 最终的意图操作;
4、flag: 控制标记位。

创建 PendingIntent 时有一个容易犯错的地方需要注意:重复调用 PendingIntent.getActivity() 等创建方法不一定会返回新的对象,系统会基于两个要素判断是否需要返回相同的对象

  • 要素 1 - requestCode: 不同的 requestCode 会被认为不同的 PendingIntent 意图;
  • 要素 2 - Intent: 不同的 Intent 会被认为不同的 PendingIntent 意图,但并不是 Intent 中所有的参数都会参与计算,而是仅包含 Intent.filterEquals() 方法考虑的参数,即:action、data、type、identity、class 和 cateGories,但不包括 extras。

PendingIntent 标记位

  • FLAG_IMMUTABLE: 不可变标记位,将约束外部应用消费 PendingIntent 修改其中的 Intent;
  • FLAG_MUTABLE: 可变标记位,不约束外部应用消费 PendingIntent 修改其中的 Intent;
  • FLAG_UPDATE_CURRENT: 更新标记位 1,如果系统中已经存在相同的 PendingIntent,那么将保留原有 PendingIntent 对象,而更新其中的 Intent。即使不可变 PendingIntent,依然可以在当前应用更新;
  • FLAG_CANCEL_CURRENT: 更新标记位 2,如果系统中已经存在相同的 PendingIntent,那么将先取消原有的 PendingIntent,并重新创建新的 PendingIntent。
  • FLAG_NO_CREATE: 更新标记位 3,如果系统中已经存在相同的 PendingIntent,那么不会重新创建,而是直接返回 null;
  • FLAG_ONE_SHOT: 一次有效标记位,PendingIntent 被消费后不支持重复消费,即只能使用一次。

2、闹钟任务设置

闹钟执行方法设置

1)一次性执行

alarmMgr.set(@AlarmType int type, long triggerAtMillis, PendingIntent operation)

2)重复执行

setRepeating()和setInexactRepeating()都可以设置重复任务,官方推荐使用setInexactRepeating()

alarmMgr.setInexactRepeating(@AlarmType int type, long triggerAtMillis, long intervalMillis, PendingIntent operation)

type,闹钟类型
triggerAtMillis,首次触发时间,毫秒数
intervalMillis,每次执行时间间隔,毫秒数

闹钟类型说明:

  • ELAPSED_REALTIME - 基于自设备启动以来所经过的时间触发待定 intent,但不会唤醒设备。经过的时间包括设备处于休眠状态期间的任何时间。
  • ELAPSED_REALTIME_WAKEUP - 唤醒设备,并在自设备启动以来特定时间过去之后触发待定 Intent。
  • RTC - 在指定的时间触发待定 Intent,但不会唤醒设备。
  • RTC_WAKEUP - 唤醒设备以在指定的时间触发待定 Intent。

3、AlarmManager代码示例

一次性任务,1分钟后执行

private AlarmManager alarmMgr;private PendingIntent alarmIntent;...alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);Intent intent = new Intent(context, AlarmReceiver.class);alarmIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT| PendingIntent.FLAG_IMMUTABLE);alarmMgr.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 60 * 1000, alarmIntent);

重复任务,30分钟后执行,每间隔30分钟执行1次,注意:最短间隔时间是1分钟

private AlarmManager alarmMgr;private PendingIntent alarmIntent;...alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);Intent intent = new Intent(context, MyIntentService.class);alarmIntent = PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT| PendingIntent.FLAG_IMMUTABLE);alarmMgr.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,        SystemClock.elapsedRealtime() + AlarmManager.INTERVAL_HALF_HOUR,        AlarmManager.INTERVAL_HALF_HOUR, alarmIntent);

在下午 2:00 左右唤醒设备并触发闹钟,并在每天的同一时间重复一次

// 设置闹钟在下午2:00执行Calendar calendar = Calendar.getInstance();calendar.setTimeInMillis(System.currentTimeMillis());calendar.set(Calendar.HOUR_OF_DAY, 14);// 设置每隔一天执行一次alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),        AlarmManager.INTERVAL_DAY, alarmIntent);

在上午 8:30 准时唤醒设备并触发闹钟,此后每 20 分钟触发一次

private AlarmManager alarmMgr;private PendingIntent alarmIntent;...alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);Intent intent = new Intent(context, AlarmReceiver.class);alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);// 设置闹钟在上午8:30 执行Calendar calendar = Calendar.getInstance();calendar.setTimeInMillis(System.currentTimeMillis());calendar.set(Calendar.HOUR_OF_DAY, 8);calendar.set(Calendar.MINUTE, 30);// 设置闹钟每隔20分钟触发一次alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),        1000 * 60 * 20, alarmIntent);

4、取消Alarm任务

使用PendingIntent.FLAG_NO_CREATE获取已存在的PendingIntent,然后执行cancel()方法

Intent intent = new Intent(this, MyIntentService.class);AlarmManager alarmManager = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);PendingIntent pendingIntent = PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_IMMUTABLE);if (pendingIntent != null && alarmManager != null) {    Log.i("cancelAlarm", "cancelAlarm: " + pendingIntent);    pendingIntent.cancel();    alarmManager.cancel(pendingIntent);} else {    Log.i("cancelAlarm", "not found Alarm !");}

5、在设备重启时启动闹钟

1)添加设备权限

2)实现 BroadcastReceiver 以接收广播,判断设备启动事件

public class SampleBootReceiver extends BroadcastReceiver {    @Override    public void onReceive(Context context, Intent intent) {        if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {            // 判断设备启动事件        }    }}

3)配置 Intent 过滤器过滤器,添加android.intent.action.BOOT_COMPLETED

                

二、使用 WorkManager 调度任务

本节参考官方文档:https://developer.android.google.cn/topic/libraries/architecture/workmanager/basics

WorkManager 是适合用于持久性工作的推荐解决方案。如果工作始终要通过应用重启和系统重新启动来调度,便是持久性的工作。由于大多数后台处理操作都是通过持久性工作完成的,因此 WorkManager 是适用于后台处理操作的主要推荐 api

  • 立即,一次性,OneTimeWorkRequest 和 Worker。如需处理加急工作,请对 OneTimeWorkRequest 调用 setExpedited()。
  • 长期运行,一次性或定期,任意 WorkRequest 或 Worker。在工作器中调用 setForeground() 来处理通知。
  • 可延期,一次性或定期,PeriodicWorkRequest 和 Worker。

WorkManager 适用于需要可靠运行的工作,即使用户导航离开屏幕、退出应用或重启设备也不影响工作的执行。例如:

WorkManager 不适用于那些可在应用进程结束时安全终止的进程内后台工作。它也并非对所有需要立即执行的工作都适用的通用解决方案。

WorkManager 的使用简单描述3个步骤

  1. 定义工作,创建Worker实现类
  2. 创建工作请求,WorkRequest
  3. 将 WorkRequest 提交给系统

1、引入依赖包

将以下依赖项添加到应用的build.gradle文件中

dependencies {    def work_version = "2.7.1"    // (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"}

2、定义工作

工作使用 Worker 类定义。doWork() 方法在 WorkManager 提供的后台线程上异步运行。

如需为 WorkManager 创建一些要运行的工作,请扩展 Worker 类并替换 doWork() 方法。例如,如需创建上传图像的 Worker,您可以执行以下操作:

public class UploadWorker extends Worker {    public UploadWorker(            @NonNull Context context,            @NonNull WorkerParameters params) {        super(context, params);    }    @Override    public Result doWork() {        // 获取传入的参数        String name = getInputData().getString("name");        Log.i("Worker", "uploadImages: name: "+ name);        uploadImages();        return Result.success();    }    private void uploadImages() {        Log.i("Worker", "uploadImages: test2");    }}

从 doWork() 返回的 Result 会通知 WorkManager 服务工作是否成功,以及工作失败时是否应重试工作。

  • Result.success():工作成功完成。
  • Result.failure():工作失败。
  • Result.retry():工作失败,应根据其重试政策在其他时间尝试。

3、创建 WorkRequest

定义工作后,必须使用 WorkManager 服务进行调度该工作才能运行。对于如何调度工作,WorkManager 提供了很大的灵活性。您可以将其安排为在某段时间内定期运行,也可以将其安排为仅运行一次。

不论您选择以何种方式调度工作,请始终使用 WorkRequest。Worker 定义工作单元,WorkRequest(及其子类)则定义工作运行方式和时间。

  • OneTimeWorkRequest,一次性任务
  • PeriodicWorkRequest,周期任务

1)OneTimeWorkRequest 示例

WorkRequest uploadWorkRequest =   new OneTimeWorkRequest.Builder(UploadWorker.class)       .build();

2)PeriodicWorkRequest 示例

PeriodicWorkRequest 最短执行周期是15分钟,如果设置的循环周期小于15分钟也会被设置为15分钟
最好给WorkRequest设置Tag值,以便在启动时,删除旧的执行任务,防止重复执行

PeriodicWorkRequest uploadWorkRequest =        new PeriodicWorkRequest.Builder(UploadWorker.class, 15, TimeUnit.MINUTES)                // Constraints                .setInitialDelay(10, TimeUnit.SECONDS)                .addTag("task")                .setInputData(new Data.Builder()                        .putString("name","Hello")                        .build())                .build();

4、将 WorkRequest 提交给系统

最后,您需要使用 enqueue() 方法将 WorkRequest 提交到 WorkManager。

WorkManager    .getInstance(this)    .enqueue(uploadWorkRequest);

如果要要取消任务可使用方法

// 取消所有任务WorkManager.getInstance(this).cancelAllWork();// 取消指定任务WorkManager.getInstance(this).cancelAllWorkByTag("task");

其他配置

执行加急工作

您可以控制当应用达到其执行配额时加急工作会发生什么情况。如需继续,您可以传递 setExpedited():

  • OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST,这会导致作业作为普通工作请求运行。上述代码段演示了此操作。
  • OutOfQuotaPolicy.DROP_WORK_REQUEST,这会在配额不足时导致请求取消。
OneTimeWorkRequest request = new OneTimeWorkRequestBuilder()    .setInputData(inputData)    .setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)    .build();

工作约束

约束可确保将工作延迟到满足最佳条件时运行

  • NetworkType 约束运行工作所需的网络类型。例如 Wi-Fi (UNMETERED)。
  • BatteryNotLow 如果设置为 true,那么当设备处于“电量不足模式”时,工作不会运行。
  • RequiresCharging 如果设置为 true,那么工作只能在设备充电时运行。
  • DeviceIdle 如果设置为 true,则要求用户的设备必须处于空闲状态,才能运行工作。在运行批量操作时,此约束会非常有用;若是不用此约束,批量操作可能会降低用户设备上正在积极运行的其他应用的性能。
  • StorageNotLow 如果设置为 true,那么当用户设备上的存储空间不足时,工作不会运行。
Constraints constraints = new Constraints.Builder()       .setRequiredNetworkType(NetworkType.UNMETERED)       .setRequiresCharging(true)       .build();WorkRequest myWorkRequest =       new OneTimeWorkRequest.Builder(MyWork.class)               .setConstraints(constraints)               .build();

重试和退避政策

如果您需要让 WorkManager 重试工作,可以从工作器返回 Result.retry()。然后,系统将根据退避延迟时间和退避政策重新调度工作。

  • 退避延迟时间指定了首次尝试后重试工作前的最短等待时间。此值不能超过 10 秒(或 MIN_BACKOFF_MILLIS)。
  • 退避政策定义了在后续重试过程中,退避延迟时间随时间以怎样的方式增长。WorkManager 支持 2 个退避政策,即 LINEAR(线性) 和 EXPONENTIAL(指数)。

每个工作请求都有退避政策和退避延迟时间。默认政策是 EXPONENTIAL,延迟时间为 10 秒,但您可以在工作请求配置中替换此设置。

WorkRequest myWorkRequest =       new OneTimeWorkRequest.Builder(MyWork.class)               .setBackoffCriteria(                       BackoffPolicy.LINEAR,                       OneTimeWorkRequest.MIN_BACKOFF_MILLIS,                       TimeUnit.MILLISECONDS)               .build();

链接工作,执行多个工作

您可以使用 WorkManager 创建工作链并将其加入队列。工作链用于指定多个依存任务并定义这些任务的运行顺序。
如需创建工作链,您可以使用 WorkManager.beginWith(OneTimeWorkRequest) 或 WorkManager.beginWith(List),这会返回 WorkContinuation 实例

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();

总结

  • AlarmManager,会使设备从低电耗模式中唤醒。因此,它在电源和资源管理方面来讲并不高效。AlarmManager 仅适合用于精确闹钟或通知(例如日历活动)场景,而不适用于后台工作。
  • WorkManager,使用更加简单,适用于更加复杂的场景,兼容性更好

来源地址:https://blog.csdn.net/wlddhj/article/details/128257612

--结束END--

本文标题: Android开发之定时任务(AlarmManager、WorkManager)

本文链接: https://www.lsjlt.com/news/373629.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Android开发之定时任务(AlarmManager、WorkManager)
    Android 程序的定时任务主要有AlarmManager、WorkManager两种。 一、AlarmManager AlarmManager,又称闹钟,可以设置一次性任务,周期重复任务,定时重复任务。 AlarmManager 通过 ...
    99+
    2023-08-18
    android java 开发语言
  • Android中alarmmanager定时任务怎么实现
    在Android中,可以使用`AlarmManager`类来实现定时任务。下面是一个基本的步骤:1. 创建一个`PendingInt...
    99+
    2023-10-08
    Android
  • SpringBoot开发实战系列之动态定时任务
    目录前言代码编写效果演示  启动修改停止后记前言 定时器是我们项目中经常会用到的,SpringBoot使用@Scheduled注解可以快速启用一个简单的定时器(详情请看我们之前的博客...
    99+
    2024-04-02
  • jspXCMS怎么开发定时任务
    这篇文章主要介绍了jspXCMS怎么开发定时任务的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇jspXCMS怎么开发定时任务文章都会有所收获,下面我们一起来看看吧。系统中有定时任务功能,里面有一些系统已经定义好...
    99+
    2023-06-26
  • 详解SpringBoot开发案例之整合定时任务(Scheduled)
    来来来小伙伴们,基于上篇的邮件服务,定时任务就不单独分项目了,天然整合进了邮件服务中。不知道,大家在工作之中,经常会用到那些定时任务去执行特定的业务,这里列举一下我在工作中曾经使用到的几种实现。任务介绍 Java自带的java.util....
    99+
    2023-05-31
    spring boot 定时任务
  • 若依之定时任务
    若依之定时任务 定时任务实现与介绍 若依中定时任务是使用Quartz实现的,首先需要导入Quartz的依赖 org.quartz-scheduler quartz ...
    99+
    2023-08-28
    java spring Quartz 定时任务 若依
  • Jspxcms定时任务的开发是怎样的
    本篇文章为大家展示了Jspxcms定时任务的开发是怎样的,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。系统中有定时任务功能,里面有一些系统已经定义好的任务类型。如果系统自带的任务类型里没有自己需要的...
    99+
    2023-06-26
  • python 包之 APScheduler 定时任务
    目录一、安装二、定时执行一次三、间隔执行四、每日定时执行一次五、每几分钟执行一次六、每小时执行一次七、调度器分类一、安装 pip install apscheduler 二、定时执行...
    99+
    2024-04-02
  • Android实现定时任务功能
    本文实例为大家分享了Android实现定时任务功能的具体代码,供大家参考,具体内容如下 1、采用Handle与线程的sleep(long)方法 (1)、定义一个Handler类,用于...
    99+
    2024-04-02
  • android怎么定时执行任务
    在Android中,有几种方法可以定时执行任务。以下是其中的一些方法:1. 使用Handler和Runnable:可以通过Handl...
    99+
    2023-09-26
    android
  • Android自定义定时闹钟开发
    本文实例为大家分享了Android开发之自定义闹钟实现,供大家参考,具体内容如下 闹钟时间设置及显示 闹钟的布局很简单,就是一个简单时间设置,所以自己写一个简单的布局按钮之类的也可以...
    99+
    2024-04-02
  • android定时任务如何关闭
    要关闭Android上的定时任务,可以按照以下步骤进行操作:1. 打开设备的设置应用程序。2. 在设置中,找到“应用程序”或“应用和...
    99+
    2023-09-21
    android
  • SpringBoot任务之定时任务相关知识总结
    01: 异步任务 03: 邮件任务 一、SpringBoot--任务:定时任务 项目开发中经常需要执行一些定时任务,比如需要在每天凌晨的时候, 分析一次前一天的日志信息,Spri...
    99+
    2024-04-02
  • java定时任务如何触发
    在Java中,可以使用java.util.Timer类或者java.util.concurrent.ScheduledExecuto...
    99+
    2023-08-29
    java
  • oracle定时任务怎么开启
    oracle 定时任务启用指南:步骤: 创建专用于运行任务的用户,授予 create job 和 alter job 权限。步骤: 创建角色并授予 execute job 权限。步骤: ...
    99+
    2024-04-08
    oracle
  • android定时执行任务怎么设置
    在Android中,可以使用AlarmManager类来设置定时执行的任务。下面是一个简单的示例:1. 首先,在AndroidMan...
    99+
    2023-08-18
    android
  • android定时执行任务怎么实现
    Android定时执行任务可以通过以下几种方式实现:1. 使用Handler和Timer:创建一个Handler对象,在Handle...
    99+
    2023-09-21
    android
  • SpringBoot任务之定时任务的知识点有哪些
    这篇文章主要为大家展示了“SpringBoot任务之定时任务的知识点有哪些”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“SpringBoot任务之定时任务的知识点有哪些”这篇文章吧。一、Spri...
    99+
    2023-06-15
  • 如何利用Redis和Groovy开发定时任务功能
    如何利用Redis和Groovy开发定时任务功能引言:定时任务是现代软件开发中常见的需求之一,它能够在预定的时间点或间隔时间内自动执行特定的代码逻辑。在本文中,我们将介绍如何利用Redis和Groovy开发定时任务功能,并给出具体的代码示例...
    99+
    2023-10-22
    redis Groovy 定时任务
  • Java之SpringBoot定时任务案例讲解
    1. SpringBoot--任务:定时任务 项目开发中经常需要执行一些定时任务,比如需要在每天凌晨的时候, 分析一次前一天的日志信息,Spring为我们提供了异步执行任务调度的...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作