Android定时功能AlarmMananger使用不怎么详细的详解

  大多时候,我们可能需要用到定时的功能,一般来说使用handle和TimeTask都可以实现定时,但是有些时候系统级别的定时这两个就出现了短板。如果我们需要一个功能比如:每2小时重启设备。这个时候,使用AlarmManager就非常实用了。

我们可以先了解一下AlarmManager:This class provides access to the system alarm services. These allow you to schedule your application to be run at some point in the future. When an alarm goes off, the Intent that had been registered for it is broadcast by the system, automatically starting the target application if it is not already running. Registered alarms are retained while the device is asleep (and can optionally wake the device up if they go off during that time), but will be cleared if it is turned off and rebooted.

上面的英文,是用来装逼的。。。。。。。。。。

你是不是说看不懂。。。。。。。。。。

我也看不懂。。。。。。。。

    大概的意思就是说:该类提供访问系统闹钟服务,允许你的app某个固定时间段去使用系统广播开启意图(Intent)为所欲为(比如开启一个activity,broadcast,service)。如果你的设备处于休眠状态,则你设置的会被保留,下次唤醒就可以继续为所欲为。(ps:当然这是取决你自己设置的Alarm

Type,后面说)。

接下来说一说怎么用:

  (1)在Android中我们先获取AlarmManager对象:

AlarmManager publicManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);

(2)使用PendingIntent 延迟意图,携带intent,开启广播、服务、activity

getActivity(Context, int, Intent, int)  跳转到一个activity组件

getBroadcast(Context, int, Intent, int) 打开一个广播组件

getService(Context, int, Intent, int) 打开一个服务组件。

    举个栗子:

PendingIntent locationPending = PendingIntent.getBroadcast(context, 0, locationIntent, 0);

那么其中4个参数还是需要说明一下:

Context:不说了

第二个:int requestCode : 这个应该都是知道的,请求码,区分intent

第三个intent :不解释了,。。。

第四个int:创建怎么样类型的pendingIntent;()

a:FLAG_ONE_SHOT:意图只能被使用一次。

b:FLAG_NO_CREATE: 如果intent不存在则不创建,返回null;

c:FLAG_CANCEL_CURRENT:如果PedingIntent已经存在,则需要取消存在的,重新创建一个;

d:FLAG_UPDATE_CURRENT:PendingIntent不会被重新创建,而是更新你intent携带的数据,可以实现extra数据更新(用的比较多);

    (还有几个就不说了);

(3)pendingIntent的方法

        接下来讲一下他的API,提供我们使用;我先列出几个方法:

    set (int type,  long triggerAtMillis, PendingIntent operation);

    setAndAllowWhileIdle (int type, long triggerAtMillis,  PendingIntent operation);

    setAlarmClock (AlarmManager.AlarmClockInfo info, PendingIntent operation);

讲之前先说明一下AlarmType:

    在使用定时任务时,基本都是需要设置这个类型的,它分为以下几种:

        1、RTC_WAKEUP:设置处于休眠状态会被唤醒,使用的是系统当前时间System.currentTimeMillis();即第二个参数long time ;状态值是0。

        2、RTC:处于休眠状态就不会醒来了,使用的是系统当前时间System.currentTimeMillis();状态值是1。

        3、ELAPSED_REALTIME_WAKEUP:即使设备处于休眠,也会被唤醒去处理事情,使用的是相对时间:SystemClock.elapsedRealtime(),从开机起计时即使在休眠状态也会被计时(time

since boot, including sleep);状态值2;

        4、ELAPSED_REALTIME:设备处于休眠时,不会唤醒设备,直到下次设备主动被唤醒才会执行。使用的是相对间:SystemClock.elapsedRealtime()状态值3;

接下来继续讲api,主要说一下常用的方法

    (1) set (int type,  long triggerAtMillis, PendingIntent operation);

            设置一次性闹钟,第一个参数表示alarm类型,第二个参数表示闹钟执行时间(比如:5000即为5s后响应),第三个参数表示响应动作。

api在19版本以上后,设置的时间可能不会准时的响应。

    (2) setAndAllowWhileIdle (int type,   long triggerAtMillis,   PendingIntent operation)

        这个方法是在api版本>23时才有的,他和set的功能是一样的,不过这个方法即使是系统处于低电耗打盹的时候也能执行。这个优化的是在耗电的情况下不会一起统一执行,而是尽可能在空闲的情况下去执行,所以你设置的时间可能会晚到15分钟后才执行。

 (3)setExact (int type,   long triggerAtMillis,  PendingIntent operation)

        跟上面两个方法是差不多的,这个是api>19版本才有的方法,他的不同之处在于他不会精准的在你设置的时间段响应闹钟,只会在尽可能接近的时候去处理。其实(2)和(3)都算是Android系统的一种功耗优化吧?

举个栗子时间到:

public void creatRemindOtaUpdateAlarm(){    Intent locationIntent =new Intent(context, LocationReceiver.class);

   locationIntent.setAction(Constants.OTAUPDATEACTION);

   locationIntent.setPackage(packageName);

   PendingIntent otaPendIntent = PendingIntent.getBroadcast(context, 0, locationIntent, 0);

   if (Build.VERSION.SDK_INT >=23/* Build.VERSION_CODES.M */) {

publicManager.setExactAndAllowWhileIdle(

AlarmManager.ELAPSED_REALTIME_WAKEUP,

               SystemClock.elapsedRealtime() +3000, otaPendIntent);//60分钟后执行12*60*60*1000

   }else if (Build.VERSION.SDK_INT >=19/* Build.VERSION_CODES.KITKAT */) {

publicManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP,

               SystemClock.elapsedRealtime() +3000, otaPendIntent);

   }

}

然后注册一个广播做你想做的事情,我是根据广播的action来判断广播的。

以上都是发送一次性闹钟,接下来讲解一下轮训定时执行的任务:

(1)setInexactRepeating (int type, long triggerAtMillis, long intervalMillis,PendingIntentoperation);

设置一个重复执行的定时器,第二个参数是第一次执行时间,第三个是下一次重复执行的时间,

这个方法设置的重复提醒时间是不固定的。

(2)setRepeating (int type,  long triggerAtMillis,long intervalMilPendingIntentoperation)

           跟第一个是差不多的,设置重复执行的闹钟。不过多解释。

需要注意的是:所有api>19的版本,设置重复提醒的闹钟都是不会精准的去响应的。

    再次举个栗子:


public void createGetAppLastVersion(){    Intent locationIntent =new Intent(context, DeviceInfoReceiver.class);

   locationIntent.setAction("com.jjj.eee.appversion");

   locationIntent.setPackage(packageName);

   PendingIntent locationPending = PendingIntent.getBroadcast(context, 0, locationIntent, 0);

   publicManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(),60*60*1000, locationPending);

}

  接下来是广播:

public class DeviceInfoReceiver extends BroadcastReceiver {

@Override

public void onReceive(Context context, Intent intent) {

if("com.jjj.eee.appversion".equals(intent.getAction())){

//todo

Log.e("WWW","接收到了广播");

}

}

}

记得在清单文件注册广播,并添加action:

   android:name=".DeviceInfoReceiver"

   android:enabled="true"

   android:exported="false">

           

好了,以上就是使用定时的闹钟了,现在说一下最重要的一个方法取消设置的定时闹钟:

cancel (PendingIntentoperation);

这个就是取消的方法,比较简单明了直接传一个PendingIntent就行了,注意这个时候你可能

需要重新去创建一个同样的PendingIntent;

贴代码比较明显:

public void cancelAppVersionAlarm(){

Intent locationIntent =new Intent(context, DeviceInfoReceiver.class);

   ​locationIntent.setAction("com.jjj.eee.appversion");

   locationIntent.setPackage(packageName);

   PendingIntent locationPending = PendingIntent.getBroadcast(context, 0, locationIntent, 0);

   publicManager.cancel(locationPending);

   LogUtil.i("app版本轮询取消!");

}


    ​ok.以上就是alarmManager,个人所了解的一些了,值得一说的是,Android在4.4版本以后对他进行了优化,也就是我们特意提醒了api>19以后的事情了,为什么会出现不精准的情况或者延迟呢?我们想一下,如果你的手机有4个应用都设置了定时,一个1分钟,一个2分钟一个3分钟这样类推下去,那么我系统是不是基本上每分钟都在执行你的这些任务,耗时耗电耗量,简直就是Android的3大功耗。这个时候Google就想到统一管理你这些了,把你们聚到一起,统一时间段都一下子做了去,你们分别是1,2,3,4分钟,那我就5分钟一起执行。大概就这总思路。。。。。。以上。。

关注个人微信:


Android定时功能AlarmMananger使用不怎么详细的详解_第1张图片
个人公众号

你可能感兴趣的:(Android定时功能AlarmMananger使用不怎么详细的详解)