精华内容
下载资源
问答
  • spring定时任务详解(@Scheduled注解)

    万次阅读 多人点赞 2016-07-07 17:09:36
    springMVC里使用spring的定时任务非常的简单,如下: (一)xml里加入task的命名空间 xmlns:task="http://www.springframework.org/schema/task" ...

    在springMVC里使用spring的定时任务非常的简单,如下:

    (一)在xml里加入task的命名空间

    xmlns:task="http://www.springframework.org/schema/task" 
    http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.1.xsd

    (二)启用注解驱动的定时任务

    <task:annotation-driven scheduler="myScheduler"/> 
    

    (三)配置定时任务的线程池

    推荐配置线程池,若不配置多任务下会有问题。后面会详细说明单线程的问题。

    <task:scheduler id="myScheduler" pool-size="5"/>

    (四)写我们的定时任务

    @Scheduled注解为定时任务,cron表达式里写执行的时机

    package com.mvc.task.impl;
    import java.text.DateFormat;
    import java.text.SimpleDateFormat;
    import java.util.concurrent.TimeUnit;
    import org.joda.time.DateTime;
    import org.springframework.scheduling.annotation.Scheduled;
    import org.springframework.stereotype.Component;
    import com.mvc.task.IATask;
    @Component
    public class ATask implements IATask{
           @Scheduled(cron="0/10 * *  * * ? ")   //每10秒执行一次    
           @Override    
           public void aTask(){    
                try {
                    TimeUnit.SECONDS.sleep(20);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
                System.out.println(sdf.format(DateTime.now().toDate())+"*********A任务每10秒执行一次进入测试");    
           }    
    }  
    package com.mvc.task.impl;
    import java.text.DateFormat;
    import java.text.SimpleDateFormat;
    import org.joda.time.DateTime;
    import org.springframework.scheduling.annotation.Scheduled;
    import org.springframework.stereotype.Component;
    import com.mvc.task.IBTask;
    @Component
    public class BTask implements IBTask{
    	   @Scheduled(cron="0/5 * *  * * ? ")   //每5秒执行一次    
    	   @Override 
    	   public void bTask(){   
    		     DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
    	         System.out.println(sdf.format(DateTime.now().toDate())+"*********B任务每5秒执行一次进入测试");    
    	   }    
    }

    spring的定时任务默认是单线程多个任务执行起来时间会有问题(B任务会因为A任务执行起来需要20S而被延后20S执行),如下图所示:



    当我们配置了线程池后再来看结果(多线程下,B任务再也不会因为A任务执行起来要20S而被延后了):

    cron表达式详解:    

    一个cron表达式有至少6个(也可能7个)有空格分隔的时间元素。

           按顺序依次为
          1  秒(0~59)
          2  分钟(0~59)
          3 小时(0~23)
          4  天(0~31)
          5 月(0~11)
          6  星期(1~7 1=SUN 或 SUN,MON,TUE,WED,THU,FRI,SAT)
          7.年份(1970-2099)
          其中每个元素可以是一个值(如6),一个连续区间(9-12),一个间隔时间(8-18/4)(/表示每隔4小时),一个列表(1,3,5),通配符。由于"月份中的日期"和"星期中的日期"这两个元素互斥的,必须要对其中一个设置?.
           0 0 10,14,16 * * ? 每天上午10点,下午2点,4点
           0 0/30 9-17 * * ?   朝九晚五工作时间内每半小时
           0 0 12 ? * WED 表示每个星期三中午12点
           "0 0 12 * * ?" 每天中午12点触发
           "0 15 10 ? * *" 每天上午10:15触发
           "0 15 10 * * ?" 每天上午10:15触发
           "0 15 10 * * ? *" 每天上午10:15触发
           "0 15 10 * * ? 2005" 2005年的每天上午10:15触发
           "0 * 14 * * ?" 在每天下午2点到下午2:59期间的每1分钟触发
           "0 0/5 14 * * ?" 在每天下午2点到下午2:55期间的每5分钟触发
           "0 0/5 14,18 * * ?" 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发
           "0 0-5 14 * * ?" 在每天下午2点到下午2:05期间的每1分钟触发
           "0 10,44 14 ? 3 WED" 每年三月的星期三的下午2:10和2:44触发
           "0 15 10 ? * MON-FRI" 周一至周五的上午10:15触发
           "0 15 10 15 * ?" 每月15日上午10:15触发
           "0 15 10 L * ?" 每月最后一日的上午10:15触发
           "0 15 10 ? * 6L" 每月的最后一个星期五上午10:15触发
           "0 15 10 ? * 6L 2002-2005" 2002年至2005年的每月的最后一个星期五上午10:15触发
           "0 15 10 ? * 6#3" 每月的第三个星期五上午10:15触发
           有些子表达式能包含一些范围或列表
           例如:子表达式(天(星期))可以为 “MON-FRI”,“MON,WED,FRI”,“MON-WED,SAT”
           “*”字符代表所有可能的值
           “/”字符用来指定数值的增量
           例如:在子表达式(分钟)里的“0/15”表示从第0分钟开始,每15分钟
                    在子表达式(分钟)里的“3/20”表示从第3分钟开始,每20分钟(它和“3,23,43”)的含义一样
           “?”字符仅被用于天(月)和天(星期)两个子表达式,表示不指定值
           当2个子表达式其中之一被指定了值以后,为了避免冲突,需要将另一个子表达式的值设为“?”
           “L” 字符仅被用于天(月)和天(星期)两个子表达式,它是单词“last”的缩写
           如果在“L”前有具体的内容,它就具有其他的含义了。例如:“6L”表示这个月的倒数第6天
           注意:在使用“L”参数时,不要指定列表或范围,因为这会导致问题
           W 字符代表着平日(Mon-Fri),并且仅能用于日域中。它用来指定离指定日的最近的一个平日。大部分的商业处理都是基于工作周的,所以 W 字符可能是非常重要的。
           例如,日域中的 15W 意味着 "离该月15号的最近一个平日。" 假如15号是星期六,那么 trigger 会在14号(星期五)触发,因为星期四比星期一离15号更近。
           C:代表“Calendar”的意思。它的意思是计划所关联的日期,如果日期没有被关联,则相当于日历中所有日期。例如5C在日期字段中就相当于日历5日以后的第一天。1C在星期字段中相当于星期日后的第一天。
           字段   允许值   允许的特殊字符
           秒           0-59           , - * /
           分           0-59           , - * /
           小时           0-23           , - * /
           日期           1-31           , - * ? / L W C
           月份           1-12 或者 JAN-DEC           , - * /
           星期           1-7 或者 SUN-SAT           , - * ? / L C #
           年(可选)           留空, 1970-2099           , - * /

    展开全文
  • 基于Springboot执行多个定时任务并且动态获取定时任务信息 基于Springboot执行多个定时任务并且动态获取定时任务信息 简介 说明 SpringApplication-启动类 动态获取定时任务信息 mapper service service impl ...
    展开全文
  • 定时任务的任务名称,cron(定时任务表达式),定时任务开关,存储数据库表中。不重启项目的情况下,修改定时任务表达式,可以实时获取新的定时任务执行时间规则;修改定时任务执行状态,可以随时开关定时任务。...

    业务场景描述:

    定时任务的任务名称,cron(定时任务表达式),定时任务开关,存储在数据库表中。在不重启项目的情况下,修改定时任务表达式,可以实时获取新的定时任务执行时间规则;修改定时任务执行状态,可以随时开关定时任务。

    使用技术:基于接口  SchedulingConfigurer

    1、建表 管理定时任务

    DROP TABLE IF EXISTS `scheduled`;
    CREATE TABLE `scheduled` (
      `name` varchar(20) DEFAULT NULL,
      `cron` varchar(30) DEFAULT NULL,
      `open` tinyint(1) DEFAULT NULL COMMENT '1开启, 其他为关闭'
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    -- ----------------------------
    -- Records of scheduled
    -- ----------------------------
    INSERT INTO `scheduled` VALUES ('demo1', '0/5 * * * * ?', '1');
    INSERT INTO `scheduled` VALUES ('demo2', '0/6 * * * * ?', '1');

    2、代码实现

    定时任务配置类:

    package com.example.demo.scheduled;
    
    import com.google.common.util.concurrent.ThreadFactoryBuilder;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.scheduling.annotation.EnableScheduling;
    import org.springframework.scheduling.annotation.SchedulingConfigurer;
    import org.springframework.scheduling.config.ScheduledTaskRegistrar;
    import org.springframework.scheduling.support.CronTrigger;
    import java.util.concurrent.Executor;
    import java.util.concurrent.Executors;
    import java.util.concurrent.ThreadFactory;
    
    /**
     * @Description: 基于接口SchedulingConfigurer的动态定时任务
     * @Author: 
     * @Date: 2020-08-27
     */
    @Configuration
    @EnableScheduling
    public abstract class ConfigurerSchedulingDemo implements SchedulingConfigurer {
    
        //定时任务周期表达式
        private String cron;
        /** 
         * @Description:  重写配置定时任务的方法
         * @param: scheduledTaskRegistrar 
         * @return: void 
         * @Author: 
         * @Date: 2020/8/28
         */
        @Override
        public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
            scheduledTaskRegistrar.setScheduler(taskScheduler());
            scheduledTaskRegistrar.addTriggerTask(
                    //执行定时任务
                    () ->
                    {
                        taskService();
                    },
                    //设置触发器
                    triggerContext -> {
    
                       cron = getCron();//获取定时任务周期表达式
    
                        CronTrigger trigger = new CronTrigger(cron);
    
                        return trigger.nextExecutionTime(triggerContext);
                    }
            );
    
        }
    
        @Bean
        public Executor taskScheduler() {
            //设置线程名称
            ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("demo-pool-%d").build();
            //创建线程池
            return Executors.newScheduledThreadPool(5, namedThreadFactory);
        }
    
        /**
         * @Description: 执行定时任务
         * @param:
         * @return: void
         * @Author: 
         * @Date: 2020/8/28
         */
        public abstract void taskService();
    
        /**
         * @Description: 获取定时任务周期表达式
         * @param:
         * @return: java.lang.String
         * @Author: 
         * @Date: 2020/8/28
         */
        public abstract String getCron();
    
    }
    

    定时任务1

    package com.example.demo.scheduled;
    
    import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
    import com.example.demo.dao.CronMapper;
    import com.example.demo.entity.Scheduled;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Configuration;
    
    import java.time.LocalDateTime;
    
    /**
     * @Description:
     * @Author: 
     * @Date: 2020-08-27
     */
    @Configuration
    public class TaskDemo extends ConfigurerSchedulingDemo {
    
        @Autowired      //注入mapper
        @SuppressWarnings("all")
        CronMapper cronMapper;
    
        @Override
        public void taskService() {
            Integer open = getOpen();
            if (1== open){
                System.out.println("定时任务demo1:"
                        + LocalDateTime.now()+",线程名称:"+Thread.currentThread().getName()
                        + " 线程id:"+Thread.currentThread().getId());
            }
        }
    
        @Override
        public String getCron() {
            QueryWrapper<Scheduled> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("name","demo1");
            String cron = cronMapper.selectOne(queryWrapper).getCron();
            return cron;
        }
    
        public Integer getOpen() {
            QueryWrapper<Scheduled> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("name", "demo1");
            Integer open = cronMapper.selectOne(queryWrapper).getOpen();
            return open;
        }
    
    }
    

       定时任务2

    package com.example.demo.scheduled;
    
    import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
    import com.example.demo.dao.CronMapper;
    import com.example.demo.entity.Scheduled;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Configuration;
    
    import java.time.LocalDateTime;
    
    /**
     * @Description:
     * @Author: 
     * @Date: 2020-08-27
     */
    @Configuration
    public class TaskDemo1 extends ConfigurerSchedulingDemo {
    
        @Autowired      //注入mapper
        @SuppressWarnings("all")
        CronMapper cronMapper;
    
        @Override
        public void taskService() {
            Integer open = getOpen();
            if (1== open){
                System.out.println("定时任务demo2:"
                        + LocalDateTime.now()+",线程名称:"+Thread.currentThread().getName()
                        + " 线程id:"+Thread.currentThread().getId());
            }
        }
    
        @Override
        public String getCron() {
            QueryWrapper<Scheduled> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("name","demo2");
            String cron = cronMapper.selectOne(queryWrapper).getCron();
            return cron;
        }
    
        public Integer getOpen() {
            QueryWrapper<Scheduled> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("name", "demo2");
            Integer open = cronMapper.selectOne(queryWrapper).getOpen();
            return open;
        }
    }
    

    效果展示:

    启动项目:控制台输出展示

    修改数据库 demo1的执行时间为每15秒一次:

    关闭demo1的定时任务,将demo1的open状态改为0:

    展开全文
  • 多种方式实现Android定时任务一款是你的FEEL?

    万次阅读 热门讨论 2016-11-25 18:08:18
    Android实现定时任务

    前言

    项目中总是会因为各种需求添加各种定时任务,所以就打算小结一下Android中如何实现定时任务,下面的解决方案的案例大部分都已在实际项目中实践,特此列出供需要的朋友参考,如果有什么使用不当或者存在什么问题,欢迎留言指出!直接上干货!

    解决方案

    普通线程sleep的方式实现定时任务

    创建一个thread,然后让它在while循环里一直运行着,通过sleep方法来达到定时任务的效果,这是最常见的,可以快速简单地实现。但是这是java中的实现方式,不建议使用

        public class ThreadTask {  
        public static void main(String[] args) {  
            final long timeInterval = 1000;  
            Runnable runnable = new Runnable() {  
                public void run() {  
                    while (true) {  
                        System.out.println("execute task");  
                        try {  
                            Thread.sleep(timeInterval);  
                        } catch (InterruptedException e) {  
                            e.printStackTrace();  
                        }  
                    }  
                }  
            };  
            Thread thread = new Thread(runnable);  
            thread.start();  
        }  
    } 

    Timer实现定时任务

    和普通线程+sleep(long)+Handler的方式比,优势在于

    • 可以控制TimerTask的启动和取消
    • 第一次执行任务时可以指定delay的时间。

    在实现时,Timer类调度任务,TimerTask则是通过在run()方法里实现具体任务(然后通过Handler与线程协同工作,接收线程的消息来更新主UI线程的内容)。

    • Timer实例可以调度多任务,它是线程安全的。当Timer的构造器被调用时,它创建了一个线程,这个线程可以用来调度任务。
       /**
        * start Timer
        */
        protected synchronized void startPlayerTimer() {
            stopPlayerTimer();
            if (playTimer == null) {
                playTimer = new PlayerTimer();
                Timer m_musictask = new Timer();
                m_musictask.schedule(playTimer, 5000, 5000);
            }
        }
    
        /**
         * stop Timer
         */
        protected synchronized void stopPlayerTimer() {
            try {
                if (playTimer != null) {
                    playTimer.cancel();
                    playTimer = null;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        public class PlayerTimer extends TimerTask {
    
            public PlayerTimer() {
            }
    
            public void run() {
                //execute task
            }
        }

    然而Timer是存在一些缺陷的

    • Timer在执行定时任务时只会创建一个线程,所以如果存在多个任务,且任务时间过长,超过了两个任务的间隔时间,会发生一些缺陷
    • 如果Timer调度的某个TimerTask抛出异常,Timer会停止所有任务的运行
    • Timer执行周期任务时依赖系统时间,修改系统时间容易导致任务被挂起(如果当前时间小于执行时间)

    注意:

    • Android中的Timer和java中的Timer还是有区别的,但是大体调用方式差不多
    • Android中需要根据页面的生命周期和显隐来控制Timer的启动和取消
      java中Timer:

      这里写图片描述

      Android中的Timer:

      这里写图片描述

    ScheduledExecutorService实现定时任务

    ScheduledExecutorService是从JDK1.5做为并发工具类被引进的,存在于java.util.concurrent,这是最理想的定时任务实现方式。
    相比于上面两个方法,它有以下好处:

    • 相比于Timer的单线程,它是通过线程池的方式来执行任务的,所以可以支持多个任务并发执行 ,而且弥补了上面所说的Timer的缺陷
    • 可以很灵活的去设定第一次执行任务delay时间
    • 提供了良好的约定,以便设定执行的时间间隔

    简例:

    public class ScheduledExecutorServiceTask 
    {  
        public static void main(String[] args) 
        {  
            final TimerTask task = new TimerTask()  
            {  
                @Override  
                public void run()  
                {  
                   //execute task  
                }  
            };   
            ScheduledExecutorService pool = Executors.newScheduledThreadPool(1);  
            pool.scheduleAtFixedRate(task, 0 , 1000, TimeUnit.MILLISECONDS);  
    
        }  
    }

    实际案例背景:

    • 应用中多个页面涉及比赛信息展示(包括比赛状态,比赛结果),因此需要实时更新这些数据

    思路分析:

    • 多页面多接口刷新
      • 就是每个需要刷新的页面基于自身需求基于特定接口定时刷新
      • 每个页面要维护一个定时器,然后基于页面的生命周期和显隐进行定时器的开启和关闭(保证资源合理释放)
      • 而且这里的刷新涉及到是刷新局部数据还是整体数据,刷新整体数据效率会比较低,显得非常笨重
    • 多页面单接口刷新
      • 接口给出一组需要实时进行刷新的比赛数据信息,客户端基于id进行统一过滤匹配
      • 通过单例封装统一定时刷新回调接口(注意内存泄露的问题,页面销毁时关闭ScheduledExecutorService )
      • 需要刷新的item统一调用,入口唯一,方便维护管理,扩展性好
      • 局部刷新,效率高
    public class PollingStateMachine implements INetCallback {
    
        private static volatile PollingStateMachine instance = null;
        private ScheduledExecutorService pool;
        public static final int TYPE_MATCH = 1;
    
        private Map matchMap = new HashMap<>();
        private List<WeakReference<View>> list = new ArrayList<>();
        private Handler handler;
    
        // private constructor suppresses
        private PollingStateMachine() {
            defineHandler();
            pool = Executors.newSingleThreadScheduledExecutor();
            pool.scheduleAtFixedRate(new Runnable() {
                @Override
                public void run() {
                    doTasks();
                }
            }, 0, 10, TimeUnit.SECONDS);
        }
    
        private void doTasks() {
            ThreadPoolUtils.execute(new PollRunnable(this));
        }
    
        public static PollingStateMachine getInstance() {
            // if already inited, no need to get lock everytime
            if (instance == null) {
                synchronized (PollingStateMachine.class) {
                    if (instance == null) {
                        instance = new PollingStateMachine();
                    }
                }
            }
            return instance;
        }
        public <VIEW extends View> void subscibeMatch(VIEW view, OnViewRefreshStatus onViewRefreshStatus) {
            subscibe(TYPE_MATCH,view,onViewRefreshStatus);
        }
    
        private <VIEW extends View> void subscibe(int type, VIEW view, OnViewRefreshStatus onViewRefreshStatus) {
            view.setTag(onViewRefreshStatus);
            if (type == TYPE_MATCH) {
                onViewRefreshStatus.update(view, matchMap);
            } 
            for (WeakReference<View> viewSoftReference : list) {
                View textView = viewSoftReference.get();
                if (textView == view) {
                    return;
                }
            }
            WeakReference<View> viewSoftReference = new WeakReference<View>(view);
            list.add(viewSoftReference);
        }
    
        public void updateView(final int type) {
            Iterator<WeakReference<View>> iterator = list.iterator();
            while (iterator.hasNext()) {
                WeakReference<View> next = iterator.next();
                final View view = next.get();
                if (view == null) {
                    iterator.remove();
                    continue;
                }
                Object tag = view.getTag();
                if (tag == null || !(tag instanceof OnViewRefreshStatus)) {
                    continue;
                }
                final OnViewRefreshStatus onViewRefreshStatus = (OnViewRefreshStatus) tag;
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        if (type == TYPE_MATCH) {
                            onViewRefreshStatus.update(view, matchMap);
                        } 
                    }
                });
    
            }
        }
    
        public void clear() {
            pool.shutdown();
            instance = null;
        }
    
        private Handler defineHandler() {
            if (handler == null && Looper.myLooper() == Looper.getMainLooper()) {
                handler = new Handler();
            }
            return handler;
        }
    
    
        @Override
        public void onNetCallback(int type, Map msg) {
            if (type == TYPE_MATCH) {
                matchMap=msg;
            } 
            updateView(type);
        }
    }
    

    需要刷新的item调用

    PollingStateMachine.getInstance().subscibeMatch(tvScore, new OnViewRefreshStatus<ScoreItem, TextView>(matchViewItem.getMatchID()) {
                @Override
                public void OnViewRefreshStatus(TextView view, ScoreItem scoreItem) {
                    //刷新处理
                    }
            });

    网络数据回调接口

    public interface INetCallback {
    
        void onNetCallback(int type,Map msg);
    
    }

    刷新回调接口:

    public abstract class OnViewRefreshStatus<VALUE, VIEW extends View> {
        private static final String TAG = OnViewRefreshStatus.class.getSimpleName();
        private long key;
    
        public OnViewRefreshStatus(long key) {
            this.key = key;
        }
    
        public long getKey() {
            return key;
        }
    
        public void update(final VIEW view, Map<Long, VALUE> map) {
            final VALUE value = map.get(key);
    
            if (value == null) {
                return;
            }
            OnViewRefreshStatus(view, value);
    
        }
    
    
        public abstract void OnViewRefreshStatus(VIEW view, VALUE value);
    
    }

    Handler实现定时任务

    通过Handler延迟发送消息的形式实现定时任务。

    • 这里通过一个定时发送socket心跳包的案例来介绍如何通过Handler完成定时任务

    案例背景

    • 由于移动设备的网络的复杂性,经常会出现网络断开,如果没有心跳包的检测, 客户端只会在需要发送数据的时候才知道自己已经断线,会延误,甚至丢失服务器发送过来的数据。 所以需要提供心跳检测

    下面的代码只是用来说明大体实现流程

    • WebSocket初始化成功后,就准备发送心跳包
    • 每隔30s发送一次心跳
    • 创建的时候初始化Handler,销毁的时候移除Handler消息队列
    private static final long HEART_BEAT_RATE = 30 * 1000;//目前心跳检测频率为30s
    private Handler mHandler;
    private Runnable heartBeatRunnable = new Runnable() {
            @Override
            public void run() {
                // excute task
                mHandler.postDelayed(this, HEART_BEAT_RATE);
            }
        };
    public void onCreate() {
         //初始化Handler
        }
    
    //初始化成功后,就准备发送心跳包
    public void onConnected() {
            mHandler.removeCallbacks(heartBeatRunnable);
            mHandler.postDelayed(heartBeatRunnable, HEART_BEAT_RATE);
        }
    
    public void onDestroy() {
            mHandler.removeCallbacks(heartBeatRunnable)
        }

    注意:这里开启的runnable会在这个handler所依附线程中运行,如果handler是在UI线程中创建的,那么postDelayed的runnable自然也依附在主线程中。

    AlarmManager实现精确定时操作

    我们使用Timer或者handler的时候会发现,delay时间并没有那么准。如果我们需要一个严格准时的定时操作,那么就要用到AlarmManager,AlarmManager对象配合Intent使用,可以定时的开启一个Activity,发送一个BroadCast,或者开启一个Service.

    案例背景

    • 在比赛开始前半个小时本地定时推送关注比赛的提醒信息

    AndroidManifest.xml中声明一个全局广播接收器

      <receiver
                android:name=".receiver.AlarmReceiver"
                android:exported="false">
                <intent-filter>
                    <action android:name="${applicationId}.BROADCAST_ALARM" />
                </intent-filter>
            </receiver>

    接收到action为IntentConst.Action.matchRemind的广播就展示比赛
    提醒的Notification

    public class AlarmReceiver extends BroadcastReceiver {
        private static final String TAG = "AlarmReceiver";
    
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent == null) {
                return;
            }
            String action = intent.getAction();
            if (TextUtils.equals(action, IntentConst.Action.matchRemind)) {
                //通知比赛开始
                long matchID = intent.getLongExtra(Net.Param.ID, 0);
                showNotificationRemindMe(context, matchID);
            }
    
        }
    }

    AlarmUtil提供设定闹铃和取消闹铃的两个方法

    public class AlarmUtil {
        private static final String TAG = "AlarmUtil";
    
        public static void controlAlarm(Context context, long startTime,long matchId, Intent nextIntent) {
            AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
            PendingIntent pendingIntent = PendingIntent.getBroadcast(context, (int) matchId, nextIntent,
                    PendingIntent.FLAG_ONE_SHOT);
            alarmManager.set(AlarmManager.RTC_WAKEUP, startTime, pendingIntent);
        }
    
        public static void cancelAlarm(Context context, String action,long matchId) {
            Intent intent = new Intent(action);
            PendingIntent sender = PendingIntent.getBroadcast(
                    context, (int) matchId, intent, 0);
    
            // And cancel the alarm.
            AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
            alarmManager.cancel(sender);
        }
    
    
    }

    关注比赛的时候,会设置intent的action为IntentConst.Action.matchRemind,会根据比赛的开始时间提前半小时设定闹铃时间,取消关注比赛同时取消闹铃

       if (isSetAlarm) {
                long start_tm = matchInfo.getStart_tm();
                long warmTime = start_tm - 30 * 60;
    
                Intent intent = new Intent(IntentConst.Action.matchRemind);
                intent.putExtra(Net.Param.ID, matchInfo.getId());
                AlarmUtil.controlAlarm(context, warmTime * 1000,matchInfo.getId(), intent);
    
                Gson gson = new Gson();
                String json = gson.toJson(matchInfo);
                SportDao.getInstance(context).insertMatchFollow(eventID, matchInfo.getId(), json, matchInfo.getType());
            } else {
                AlarmUtil.cancelAlarm(context, IntentConst.Action.matchRemind,matchInfo.getId());
                SportDao.getInstance(context).deleteMatchFollowByID(matchInfo.getId());
            }
    展开全文
  • linux 定时任务实战 本文将以实例学习,如何 linux 中定时执行脚本任务。 添加定时任务 执行命令: crontab -e 进入编辑模式,添加定时任务:  //每隔1分钟执行一次 */1 * * * * /root/test_demo.sh //...
  • windows定时任务

    万次阅读 2018-01-26 09:58:54
    windows系统中创建定时任务,与linux中创建定时任务是不同的。因为平时会用到windows的定时任务,所以这里做个记录,同事给小伙伴们一个参考。
  • 二、基于接口(SchedulingConfigurer) 前者相信大家都很熟悉,但是实际使用中我们往往想从数据库中读取指定时间来动态执行定时任务,这时候基于接口的定时任务就派上用场了。 三、基于注解设定多线程定时任务 一...
  • Spring+Quartz实现定时任务的配置方法

    万次阅读 多人点赞 2019-07-31 19:16:18
    任务有并行和串行之分,并行是指:一个定时任务,当执行时间到了的时候,立刻执行此任务,不管当前这个任务是否执行中;串行是指:一个定时任务,当执行时间到了的时候,需要等待当前任务执行完毕,再去执行下一个...
  • 直接上图: 框出的一行就是新建的测试定时任务。具体步骤开始讲解: 1、先win +r组合键打开,然后...4、点击右侧的“创建任务”按钮,弹出“创建任务”的界面,“常规”列中输入定时任务的名称“测试定时任务”...
  • Springboot整合异步任务和定时任务

    万次阅读 2020-02-28 00:19:31
    使用Springboot整合的定时任务和异步任务处理
  • 分布式定时任务对比

    万次阅读 多人点赞 2018-03-07 14:42:26
    1. 什么是分布式定时任务 把分散的,可靠性差的计划任务纳入统一的平台,并实现集群管理调度和分布式部署的一种定时任务的管理方式。叫做分布式定时任务。 2. 常见开源方案  elastic-job , xxl-job ,quartz ,...
  • linux 系统定时任务 服务 详解

    千次阅读 多人点赞 2021-08-18 13:58:03
    定时任务 配置方法2.1定时任务相关文件2.2定时任务编写格式2.3 编写步骤2.4定时任务编写注意事项:(规范)总结 Centos 7 定时服务详解介绍 企业中,存在很多数据需要备份,那么我们如何让这些数据,每天晚上23:59 ...
  • 分省定时将销号数据放到SFTP服务器上,我需要开发定时任务去解析文件。因为是多省份,服务器、文件名规则、数据规则都不一定,所以要做成可配置是有一定难度的。数据规则这块必须强烈要求统一,服务器、文件名规则都...
  • linux定时任务

    万次阅读 2021-02-22 17:42:37
    批量添加任务 (echo '*/5 * * * * /rssp/code/test.sh' ;crontab -l) |crontab
  • java 定时任务之一 @Scheduled注解(第一种方法)

    万次阅读 多人点赞 2017-12-12 22:09:22
    使用spring @Scheduled注解执行定时任务: 步骤: 1.xmlns 添加: http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.1.xsd xmlns:task=...
  • 一、job 定时任务的创建方式 1、使用线程创建 job 定时任务 /** * TODO 使用线程创建 job 定时任务 * @author 王松 * @date 2019/9/14 0014 22:12 */ public class JobThread { public static class Demo01 { ...
  • Linux系统定时任务

    万次阅读 2018-08-24 16:55:42
    Linux系统定时任务 定时任务Crond Crond是linux系统中用来定期执行命令/脚本或指定程序任务的一种服务或软件,一般情况下,我们安装完Centos5/6 linux操作系统之后,默认便会启动Crond任务调度服务。 Crond服务...
  • 分布式定时任务

    千次阅读 2019-08-02 16:46:10
    分布式定时任务 1,什么是分布式定时任务;2,为什么要采用分布式定时任务;3,怎么样设计实现一个分布式定时任务;4,当前比较流行的分布式定时任务框架; 1,什么是分布式定时任务: 首先,我们要了解计划...
  • Hyperf定时任务

    千次阅读 2020-05-28 11:50:35
    Hyperf初体验 定时任务 项目开发难免会用到定时任务去执行一些简单的操作,学习hyperf也避免不了要去学习定时任务,写这篇文章也是参考官方文档给出的教程,希望能给一起学习的人提供帮助,如有不足欢迎指正。 ...
  • java定时任务,每天定时执行任务

    千次阅读 2017-10-20 00:33:56
    java定时任务,每天定时执行任务
  • ubuntu 定时任务

    千次阅读 2018-05-30 17:25:30
    定制定时任务sudo crontab -e文件中输入任务命令*/1 * * * * /bin/sh /etc/init.d/test.sh此命令每分钟执行一次test.sh脚本或1 * * * * cd /etc/init.d &amp;&amp; ./test.sh &gt;&gt; /home/log...
  • Java定时任务

    千次阅读 2012-04-04 17:44:40
    日常工作中,定时进行任务...Java中由两个类完成定时任务的调度,分别为:java.util.Timer和java.util.TimerTask 创建一个定时任务的步聚: 1、创建一个定时器(Timer)对象 2、调用该对象的schedule(TimerTask
  • 所以实现定时任务都是循环的执行某一个脚本。 PHP定时任务实现主要有两个方向: 1、循环脚本本身或脚本中代码循环执行 2、服务器定时调用php 先主要介绍php脚本循环执行方案: 方案1: 脚本中的代码循环...
  • Spring定时任务

    千次阅读 2018-04-24 16:10:31
    所用的框架是基于ssm的,定时任务用的是spring的shedule,并且是注解方式,非常简便,一般比较简单的定时任务推荐这么用。 1.xml里添加task的命名空间 xmlns:task=&quot;...h...
  • crontab定时任务

    万次阅读 2019-08-23 09:42:47
    apt-get install cron #安装Crontab ...crontab -e #编辑定时任务 crontab -r #移除定时任务 crontab -l #查看定时任务 判断crond 是否运行:pgrep crond或者pgrep cron,如果有运行则返回进程号。 * * * * * /...
  • 前面的章节,用户通过绑定手机号的注册为会员,并可以补充完个人信息,比如姓名、生日等信息,拿到用户的生日信息之后,就可以通过会员生日信息进行营销,此处就涉及到定时任务执行营销信息推送的问题。本篇就带你...
  • Linux定时任务

    万次阅读 2020-09-15 23:43:51
    Linux定时任务 编写脚本 today_date="`date +%Y%m%d`" curl http://127.0.0.1:8000/$today_date/ 编辑定时工作表 crontab -e 编辑内容如下(): 30 0 * * * /home/wj/Script/auto_curl.sh >> /home/wj/...
  • SpringBoot定时任务实现

    万次阅读 多人点赞 2019-03-20 16:16:32
    最近项目中新增的需求是一系列的定时任务,设置一个结束时间,到规定的endTime之后自动结束,所以就需要我项目中设定定时任务,规定时间获取到到期的任务并将它们的状态设定为结束. 定时任务 SpringBoot中,定时...
  • spring 动态定时任务

    千次阅读 2019-06-28 10:29:06
    使用的是spring的...1. schedule(Runnable task, Date stateTime),指定时间执行一次定时任务 2. schedule(Runnable task, Trigger trigger),动态创建指定表达式cron的定时任务 3. scheduleAtFixedR...
  • Activiti 定时任务 定时边界事件

    千次阅读 2019-02-15 15:56:25
    首先需要开启 Activiti 的定时任务配置,spring-context-activiti.xml中的 &lt;property name="jobExecutorActivate" value="true" /&gt; 然后流程图中配置时间规则 这里配置的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 329,603
精华内容 131,841
关键字:

定时任务在哪看