最近项目中需要实现定时任务,安卓实现定时任务的方式有不少

短期的定时任务可以采用前三种,要实现长期精确的定时任务就看第四种AlarmManager实现

1.通过Handler + Thread 的方式

        这种方式是通过循环加线程sleep来实现

 new Thread(new Runnable() {            @Override            public void run() {                while (true){                     try {                        Thread.sleep(1000); //休眠一秒                        mHanler.sendEmptyMessage(TIMER);                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }            }        }).start();

 2.通过Handler+message

        这里通过发送延时消息不停循环调用

 private Handler mHandler = new Handler(){        @Override        public void handleMessage(Message msg) {            super.handleMessage(msg);            switch (msg.what){                case TIMER:                    //在这里去执行定时操作逻辑                                        if (flag) {                        Message message = mHandler.obtainMessage(TIMER);                        mHandler.sendMessageDelayed(message, 1000);                    }                    break;                default:                    break;            }        }    };

 3.通过TimerTask

 Timer timer = new Timer();    TimerTask task = new TimerTask() {        @Override        public void run() {            mHandler.sendEmptyMessage(TIMER);        }    };timer.schedule(task, 1000, 1000);   

4.采用AlarmManger实现长期精确的定时任务

使用场景:公司项目就要求每一天凌晨执行一下检查更新App的任务,类似的情况还有很多

AlarmManger 设置定时任务的方法有这么几个

set(int type,long startTime,PendingIntent pi);//一次性setExact(int type, long triggerAtMillis, PendingIntent operation)//一次性的精确版setRepeating(int type,long startTime,long intervalTime,PendingIntentpi);//精确重复setInexactRepeating(int type,long startTime,longintervalTime,PendingIntent pi);//非精确,降低功耗

常见使用方式:利用AlarmManger+Service+BarocastReceiver来实现可唤醒cpu,甚至实现精确定时,适用于配合service在后台执行一些长期的定时行为

startTime:闹钟的第一次执行时间,以毫秒为单位,一般使用当前时间。
intervalTime:执行时间间隔。
PendingIntent :PendingIntent用于描述Intent及其最终的行为.,这里用于获取定时任务的执行动作。

这些Api使用起来还是非常简单的,但是问题在于版本的兼容。

需要特别注意的是:

当执行任务唤醒的时候PendingIntent,在8.0版本之后获取方式不同

启动服务不在是startService() 而是startForegroundService()

if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){pendingIntent = PendingIntent.getForegroundService(context, requestCode,intent, PendingIntent.FLAG_UPDATE_CURRENT);}else{pendingIntent = PendingIntent.getService(context, requestCode,intent, PendingIntent.FLAG_UPDATE_CURRENT);}

这是由于在8.0及之后,系统对后台服务运行做了限制,如果一个后台服务没有设置前台通知startForeground,那么系统将在5s内杀死服务,并且报出ANR。这么做是为了防止应用在后台偷偷的干着不可告人的事,后台服务一多不仅卡顿还增加了功耗,消耗了流量。如果要在后台做事,google官方推荐使用jobSchedule,这个jobService实际上也是继承自Service,只对Service进行了包装,当然包装之后jobScheduler的任务都交由JobSchedulerService系统服务去调度。

jobScheduler的优点

1.把任务整合起来,等到充电状态或者 Wifi 连接情况下进行执行,充电时候就不会在乎耗电量, Wifi 连接情况下比蜂窝网络省电。

2.在系统待机的时候,把任务整合到一起,一定时间批量处理,可以避免多次的唤醒 CPU,使 CPU 得不到休息,造成耗电

综合上面的定时方案的优缺点,及项目实际情况最终考虑采用AlarmManger来实现定时任务。

有不对的地方还望指出,欢迎拍砖

 

更多相关文章

  1. tcping测试服务器TCP端口
  2. 2019-11-22 Notification(通知服务)的实例
  3. Android开发上传图片到服务器(一.图片选择)
  4. .Net程序员玩转Android开发---(20)Android绑定服务
  5. Android之通过HTTP协议向服务器发送XML数据
  6. Android(安卓)Dalvik虚拟机简述(与Java虚拟机的区别和简要的执行
  7. Android(安卓)Studio中aidl的使用示例
  8. Android通过https协议与服务器端进行通信
  9. [置顶] 让你的Android应用与外部元素互动起来

随机推荐

  1. Android碎片化问题
  2. Android带进度条的文件上传,使用AsyncTask
  3. android中ImageView设置选中与不选中颜色
  4. 最新的智能移动终端ios,android等市场占
  5. Activity启动模式 及 Intent Flags 与 栈
  6. Android 页面自动跳转方法(比如进入app的
  7. Android底部导航BottomNavigationBar的使
  8. Android(安卓)自定义权限 ( ) 和 Android
  9. 0基础,安卓搭建环境,运行HelloWord
  10. Android Gradle 配置打包输出名称格式