zoukankan      html  css  js  c++  java
  • 安卓笔记20170118

    创建定时任务

    Android的Alarm机制。

    定时任务也可以使用Java API里提供的Timer类,但它不太适用于那些需要长期在后台运行的定时任务。为了让电池更加耐用,每种手机都会有自己的休眠策略,Android手机就会在长时间不操作的情况下自动让CPU进入到睡眠状态,这就有可能导致Timer中的定时任务无法正常运行。而Alarm则具有唤醒CPU的功能,它可以保证在大多数情况下需要执行定时任务的时候CPU都能正常工作。注意:唤醒CPU和唤醒屏幕不是一个概念。

    AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        long triggerAtTime = SystemClock.elapsedRealtime() + 10 * 1000;
        manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, pendingIntent);

    set方法接收三个参数
    第一个参数是整形参数,用于指定AlarmManager的工作类型,有4种值可选

    ELAPSED_REALTIME表示让定时任务的触发时间从系统开机开始算起,但不会唤醒CPU。

    ELAPSED_REALTIME_WAKEUP同样表示让定时任务的触发时间从系统开机开始算起,但会唤醒CPU。

    RTC表示让定时任务的触发时间从1970年1月1日0点开始算起,但不会唤醒CPU。

    RTC_WAKEUP表示让定时任务的触发时间从1970年1月1日0点开始算起,但会唤醒CPU。

    使用SystemClock.elapsedRealtime()方法可以获取到系统开机至今所经历时间的毫秒数,使用System.currentTimeMillis()方法可以获取到1970年1月1日0点至今所经历时间的毫秒数

    第二个参数代表定时任务触发的时间,以毫秒为单位。

    如果第一个参数使用的是ELAPSED_REALTIME或ELAPSED_REALTIME_WAKEUP,则这里传入开机至今的时间再加上延迟执行的时间。

    如果第一个参数使用的是RTC或RTC_WAKEUP,则这里传入1970年1月1日0点至今的时间再加上延迟执行的时间。

    第三个参数是一个PendingIntent,一般会调用getService()方法或者getBroadcast()方法来获取一个能够执行服务或广播的PendingIntent。这样当定时任务被触发的时候,服务的onStartCommand()方法或广播接收器的OnReceive()方法就可以得到执行。

    实现一个长时间在后台定时运行的服务

    public class LongRunningService extends Service {
    
        @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() {
                    
                }
                
            }).start();
            AlarmManager manager = (AlarmManager) getSystemService(ALARM_SERVICE);
            int anHour = 60 * 60 * 1000;
            long triggerAtTime = SystemClock.elapsedRealtime() + anHour;
            Intent i = new Intent(this, LongRunningService.class);
            PendingIntent pi = PendingIntent.getService(this, 0, i, 0);
            manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, pi);
            return super.onStartCommand(intent, flags, startId);
        }
    
    }

    在onStartCommand()方法中开启了一个子线程,并在这里执行逻辑操作。因为逻辑操作需要耗时,如果放在主线程里执行可能会对定时任务的准确性造成轻微的影响

    最后,只需要在你想启动定时服务的时候调用如下代码即可:

    Intent intent = new Intent(context, LongRunningService.class);

    context.startService(intent);

    注意:从Android4.4系统开始,Alarm任务的触发时间将会变得不准确,有可能会延迟一段时间后任务才能得到执行。这是系统在耗电性能方面进行的优化。系统会自动检测目前有多少Alarm任务存在,然后将触发时间相近的几个任务放在一起执行,这就可以大幅度地减少CPU被唤醒的次数,从而有效延长电池的使用时间。

    如果你要求Alarm任务的执行时间必须准确无误,使用AlarmManager的setExact()方法来替代set()方法,就基本上可以保证任务能够准时执行了。

  • 相关阅读:
    了解语言学习的四个阶段,孩子的英语学习更从容
    MySQL 修改字段类型或长度
    js中退出语句break,continue和return 比较
    PHP中unset,array_splice删除数组中元素的区别
    php判断一个数组是另一个数组的子集
    PHP实现一维数组转二维数组的方法
    基于 HTML5 WebGL 的 3D 网络拓扑图
    SQL 2008下载地址以及全新安装详细过程
    php从数组中取出一段 之 array_slice
    Linux命令:cp (copy)复制文件或目录
  • 原文地址:https://www.cnblogs.com/919czzl/p/6296247.html
Copyright © 2011-2022 走看看