Android Doze模式下Alarm定时任务实现流程详解

目录
  • 定时任务
  • Doze模式

定时任务

Timer不太适合那些需要长期在后台运行的定时任务,因为每个手机都有自己的休眠策略,Android手机长时间不操作就会导致Timer定时任务无法执行,而Alarm具有唤醒CPU的功能,能保证大多数情况下,执行定时任务的时候CPU能正常工作。

 AlarmManager manager= (AlarmManager) getSystemService(Context.ACTIVITY_SERVICE);
 PendingIntent pendingIntent;
      /**
         *    SystemClock.elapsedRealtime():获取到系统开机至今所经历的毫秒数
         *    System.currentTimeMillis():1970-1-1 0:00至今所经历的毫秒数
         *
         *     ELAPSED_REALTIME:定时任务触发从系统开机算起 但不唤醒CPU
         *     ELAPSED_REALTIME_WAKEUP:定时任务触发从系统开机算起 唤醒CPU
         *     RTC:从1970-1-1 0:00算起 不唤醒CPU
         *     RTC_WAKEUP:从1970-1-1 0:00算起 唤醒CPU
         */
    /**pendIntent:一般会调用getSrervice或getBroadCast
       来获取一个能够执行服务或广播的pendingIntent,
       这样才能保证在任务被触发的时候,
       服务里的onStartCommand()和onRecive()方法被执行
      */
   long time= SystemClock.elapsedRealtime()+10*1000;//10秒钟后执行任务
   manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,time,pendingIntent);

那么要实现一个长时间在后台定时运行的服务该怎么做?

创建一个MyService类

package com.example.test;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.SystemClock;
import androidx.annotation.Nullable;
public class MyService extends Service {
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                //TODO
            }
        }).start();
        AlarmManager manager= (AlarmManager) getSystemService(ALARM_SERVICE);
        int time=60*60*1000;//一小时
        long triggerAtTime= SystemClock.elapsedRealtime()+time;
        Intent intent1=new Intent(this,MyService.class);
        PendingIntent pendingIntent=PendingIntent.getService(this,0,intent1,0);
        manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,triggerAtTime,pendingIntent);
        return super.onStartCommand(intent, flags, startId);
    }
}

可以看到先创建了一个子线程在这里执行具体的操作任务,然后就是alarm机制,定义任务触发一小时后,再使用PendingIntent指定定时处理任务的MyService,最后调用set方法设定完成。

这样就将一个长时间在后台定时运行的服务设定成功了,一旦启动了MyService,就会在onStartCommand()方法里设定一个定时任务,这样一小时后将会再次启动MyService,每隔一小时就会执行一次。

然后去使用,在manifest文件中注册服务

<service android:name=".MyService"/>

在使用的地方调用下面代码就可以。

    Intent intent=new Intent(context,MyService.class);
    context.startService(intent);

但是在Android4.4后,定时任务变得不准确,会延时一段时间才能执行,那是因为系统在耗电方面进行的优化,系统会检测有多少Alarm任务存在,将触发时间相近的几个任务放在一起执行,这样可以大幅度的减少CPU被唤醒的次数,演唱电池的使用时长。也可以使用setExact()来代替set()方法,可以保证任务能够准时执行。

Doze模式

如果设备未充电,并处于静止状态,且屏幕关闭了一段时间后,就能进入到Doze模式。

在Doze模式下,系统会对CPU、网络、Alarm等活动进行限制,从而延长电池的使用寿命。当然,系统并不会一直处于Doze模式,而是会间歇性地退出Doze模式一小段时间,在这段时间中,应用就可以去完成它的同步操作、Alarm任务等。

Doze模式下受限制的功能:

  • 网络访问被禁止。
  • 系统忽略唤醒CPU或者屏幕操作。
  • 系统不再执行WIFI扫描。
  • 系统不再执行同步服务。
  • Alarm任务将会在下次退出Doze模式的时候执行。

在Doze模式下, Alarm任务会变得相当不准,当然这种情况下对Alarm的要求也并不高,如果有特殊的要求,调用AlarmManager的setAndAllowWhileIdle()或者setExactAndAllowWhileIdle()方法就能让定时任务正常执行,和set()与setExact()的区别是一样的。

到此这篇关于Android Doze模式下Alarm定时任务实现流程详解的文章就介绍到这了,更多相关Android Alarm定时任务内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Android中使用Alarm的方法小结

    前言 在Android中,通过AlarmManager我们可以设置一些闹钟.在一些指定的时间点启动我们的服务进行处理事件. 例如每隔几小时拉取一下网络数据,或者每天8点钟提醒用户等. 而在使用AlarmManager时,注意以下几个点将会帮助你更好的使用这个特性. 触发时间增加随机性 如果设置闹钟所触发的任务中包含网络请求时,建议为这个触发时间点增加随机性. 假设设定在早上8点发起查询天气预报的网络请求,不增加随机性.那么在8点这一时刻,服务器将会收到大量的请求,造成服务器压力过大,如果设备足够

  • Android AlarmManager实现定时循环后台任务

    这篇文章使用AlarmManager实现了Android定时后台循环任务.使用场景:项目需要app每隔一段时间就去服务端请求一次接口,从而更新本地保存的信息. AlarmManager简介 AlarmManager是Android中常用的一种系统级别的提示服务,在特定的时刻为我们广播一个指定的Intent.简单的说就是我们设定一个时间,然后在该时间到来时,AlarmManager为我们广播一个我们设定的Intent,通常我们使用 PendingIntent. 项目功能简介: AlarmServi

  • Android Doze模式启用和恢复详解

    从Android 6.0(API level 23)开始,Android提出了两个延长电池使用时间的省电特性给用户.用户管理可以在没有充电的情况下管理app的行为.当用户一段时间没有使用手机的时候,Doze模式通过延缓app后台的CPU和网络活动减少电量的消耗.App Stanbdy延缓用户最近没有使用app的后台网络活动. 作为移动开发人员,我们开发的App需要有推送功能,不希望在锁屏或者不充电的时候被Doze模式干掉.那么如何检测手机进入Doze模式之后App的状态呢? 一.模拟未充电状态

  • Android使用AlarmManager设置闹钟功能

    本文实例为大家分享了Android使用AlarmManager设置闹钟的具体代码,供大家参考,具体内容如下 一.首先创建设置闹钟的布局页面activity_alarm_manager.xml <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"     xm

  • Android通过AlarmManager类实现简单闹钟功能

    Android通过AlarmManager类实现闹钟,供大家参考,具体内容如下 简介 闹钟是生活中最常用的功能了,很多App都可以加入该功能,提醒用户某个时刻要做的事情.在Android系统中可以通过AlarmManager类实现闹钟,AlarmManager类是专门用来设定在某个指定的时间去完成指定的事件.AlarmManager提供了访问系统警报的服务,只要在程序中设置了警报服务,AlarmManager就会通过onReceive()方法去还行这些事件,就算系统处于待机状态,同样不会影响运行

  • Android隐私协议提示弹窗的实现流程详解

    android studio版本:2021.2.1 例程名称:pravicydialog 功能: 1.启动app后弹窗隐私协议 2.屏蔽返回键 3.再次启动不再显示隐私协议. 本例程的绝大部分代码来自下面链接,因为本人改了一些,增加了一些功能,所以不有脸的算原创了. 下面这个例子是“正宗”app隐私协议实现方法,而且协议内容使用的是txt格式文件,据说如果使用html格式文件,各大平台在审核的时候大概率无法通过,但协议内容的还应该有更详细协议及说明的链接,我没做,暂时还没学会,会了再修改一下.

  • Windows下安装Redis的流程详解

    目录 一.简介 二.下载与安装Redis 1.下载 2.解压 3.几个重要的文件 三.环境变量配置 四.验证与连接redis 1.验证 3.连接Redis 4.设置一个key测试一下 一.简介 Redis作为常用开源的非关系型数据库,是开发中常用的数据库之一.Redis底层是使用ANSI C编写的,支持网络可基于内存和可持久化的日志型.Key-Value数据库,提供了多种语言API.(基于内存是Redis快的一个重要因素) 二.下载与安装Redis 1.下载 github上可以下载Windows

  • Android第三方开源下拉框NiceSpinner使用详解

    android原生的下拉框Spinner基本上可以满足Android开发对于下拉选项的设计需求,但现在越来越流行的下拉框不满足于Android原生提供的下拉框Spinner所提供的设计样式,而改用自定制或者第三方设计的下拉框Spinner. NiceSpinner是一个第三方开源的下拉框Spinner,其在github上的项目主页是:https://github.com/arcadefire/nice-spinner  NiceSpinner原设计效果如动图所示: 但是通常开发者对于可能还需要对

  • android studio 的下拉菜单Spinner使用详解

    一.认识Spinner Spinner其实就是一个列表选择框.不过Android的列表选择框并不需要显示下拉列表,而是相当于弹出一个菜单供用户选择. Spinner 与 Gallery 都继承了AbsSpinner,AbsSpinner 继承了AdapterView,因此它也表现出AdapterView的特征:只要为AdapterView提供Adapter即可. 1.相关属性 android:dropDownHorizontalOffset:设置列表框的水平偏移距离 android:dropDo

  • cdn模式下vue的基本用法详解

    我们知道jq是简化了dom操作,而react和vue则是通过使用虚拟dom的方式,不需要频繁的更改ui界面,而是通过更改数据的方式来更新界面.我们知道些jq插件时会在IFFE中传入jQuery,jQuery在此程序中映射为符号,这样可以避免$号被其他库覆写.其实vue中new Vue()对象,效果也是类似,可以避免vue范围类的数据或变量被污染.我们先来看一些基本的用法插入文本值 v-html 直接插入html结构 v-bind属性 <a :href="url" rel=&quo

  • Android view绘制流程详解

    绘制流程 measure 流程测量出 View 的宽高尺寸. layout 流程确定 View 的位置及最终尺寸. draw 流程将 View 绘制在屏幕上. Measure 测量流程 系统是通过 MeasureSpec 测量 View 的,在了解测量过程之前一定要了解这个 MeasureSpec . MeasureSpec MeasureSpec 是一个 32 位的 int 值打包而来的,打包为 MeasureSpec 主要是为了避免过多的对象内存分配. 为了方便操作,MeasureSpec

  • Android Bluetooth蓝牙技术使用流程详解

    在上篇文章给大家介绍了Android Bluetooth蓝牙技术初体验相关内容,感兴趣的朋友可以点击了解详情. 一:蓝牙设备之间的通信主要包括了四个步骤 设置蓝牙设备 寻找局域网内可能或者匹配的设备 连接设备 设备之间的数据传输 二:具体编程实现 1. 启动蓝牙功能 首先通过调用静态方法getDefaultAdapter()获取蓝牙适配器BluetoothAdapter,如果返回为空,则无法继续执行了.例如: BluetoothAdapter mBluetoothAdapter = Blueto

  • MVC+DAO设计模式下的设计流程详解

    DAO设计 : DAO层主要是做数据持久层的工作,负责与数据库进行联络的一些任务都封装在此,DAO层的设计首先是设计DAO的接口,然后在Spring的配置文件中定义此接口的实现类,然后就可在模块中调用此接口来进行数据业务的处理,而不用关心此接口的具体实现类是哪个类,显得结构非常清晰,DAO层的数据源配置,以及有关数据库连接的参数都在Spring的配置文件中进行配置. 在该层主要完成对象-关系映射的建立,通过这个映射,再通过访问业务对象即可实现对数据库的访问,使得开发中不必再用SQL语句编写复杂的

  • Android zygote启动流程详解

    对zygote的理解 在Android系统中,zygote是一个native进程,是所有应用进程的父进程.而zygote则是Linux系统用户空间的第一个进程--init进程,通过fork的方式创建并启动的. 作用 zygote进程在启动时,会创建一个Dalvik虚拟机实例,每次孵化新的应用进程时,都会将这个Dalvik虚拟机实例复制到新的应用程序进程里面,从而使得每个应用程序进程都有一个独立的Dalvik虚拟机实例. zygote进程的主要作用有两个: 启动SystemServer. 孵化应用

随机推荐