手把手教你写软件8. 每日,每周自动定时任务

上一篇我们提到calendar时有错误,那就是当软件退出后,关闭后台运行,下次进入的时候就不会再更新,达不到我们定时更新的效果。其实我们可以搭建数据库,每天按时更新数据库。但是总不能每天12点半人工更新吧。其实你也可以定个闹钟每天提醒你定时更新,如果你愿意的话。好了,作为程序员,能用代码解决的事就不叫事。所以我们可以用算法来实现就算后台退出了,每次打开的时候检查是否该更新,并执行是否更新。
这个问题比较复杂,我们首先来实现第一点,每日更新:

首先,什么情况下更新?
1.如果昨天的12:30到今天的12:30这段时间内没有更新,那么我们应该要更新,且只能更新一次。
2.如果这次是第一运行,那么我们应该在12:30以后进行更新,且只能更新一次
3.如果前面超过一天没有更新,那么我们一打开界面就应该更新,且只能更新一次。
注意:我们每次更新后的一天内都不能再更新,因为我们要实现每天只能更新一次

要实现以上的功能,我们得一步一步来。因为涉及到每次更新的时间,我们要用到当前在该年的天数,这里我们就不考虑闰年(这很简单,就是个判断),每次获得当前的天数与上次更新的天数进行比较,有几种情况:
1. 如果在同一天,且大于13点或等于12点大于30分,就更新一次。
2. 如果当前的天数等于更新的天数加1,说明昨天已更新,那么今天也要更新,同样大于13点或等于12点大于30分更新一次
3. 如果当前的天数大于更新的天数加1,说明超过一天没更新,那么一旦打开软件就要更新。
实现: 我们根据代码来讲解:
int []a = new int[4];             //保存现在的时间
                int []b = new int[4];              //保存上次的时间
                Calendar calendar=Calendar.getInstance();            //获取系统时间
                a[0]=calendar.get(Calendar.HOUR_OF_DAY);             //获取当前时间的小时
                a[1]=calendar.get(Calendar.MINUTE);                  //获取当前时间的分钟
                a[2]=calendar.get(Calendar.DAY_OF_YEAR);            //获得每年第几天
                a[3]=calendar.get(Calendar.DAY_OF_WEEK);            //获取当前是本周哪一天
                SharedPreferences SP=getSharedPreferences("data",MODE_PRIVATE);
                b[0]=12;
                b[1]=30;
                b[2]=SP.getInt("day_of_year",a[2]);               //获得上次更新时候的天数
                b[3]=SP.getInt("day_of_week",a[3]);               //获得上次更新时候的位置
                boolean Bo=false,bo=SP.getBoolean("isRefresh",true);  //每次更新bo的值,达到一天只更新一次的目的
                if(a[0]>13||a[0]==12&&a[1]>30) Bo=true;                //第一次更新
                if(a[2]==b[2]+1)                                       //昨天已更新
                    if(a[0]>13||a[0]==12&&a[1]>30) {Bo=true;bo=true;}
                if(a[2]>b[2]+1) {Bo=true;bo=true;}                     //多天未更新
                if(Bo&&bo){
                    SharedPreferences.Editor editor=getSharedPreferences("data",MODE_PRIVATE).edit();
                    editor.putInt("day_of_year",a[2]);
                    editor.putInt("day_of_week",a[3]);
                    editor.putBoolean("isRefresh",false);
                    editer.apply();
}



 
  

 
  


现在,我们来模拟一边过程。第一次打开页面,进入第一次更新,Bo=true,bo=true,执行一次,这里我调用了AlarmManager每个1s调用一次,所以再次调用后,Bo=true,bo=false,不能执行。一直持续到第二天,此时当你打开页面,a[2]=b[2]+1 执行昨天已更新,Bo=true,bo=true,执行一次.那么a[2]=b[2],运行第一次更新,Bo=true,bo=false。不能再运行。同理多天为更新。这样一来,就实现了每次打开页面检查并执行是否更新。

下面,我们来看看稍微有点复杂的每周日12:30的定时更新。因为牵涉到周几,所以我们要调用Calendar.DAY_OF_WEEK.这里注意,AS是国外的,按照外国人的习惯,一周的第一天是周日。那么每次更新的条件又有什么?

1.如果当前的星期几比上次更新的星期几小,比如现在星期1,上次更新星期2,那么一定经过了星期日,所以此时直接更新,同样只更新一次
2.如果当前所在该年的天数>=上次更新的天数+7,说明超过一周未更新,此时也是直接更新,且只更新一次
3.如果今天刚好周日,且大于13点或等于12点大于30分,可以更新,且只能更新一次

实现代码如下:

 boolean Ao=false,ao=SP.getBoolean("isRefresh1",true);
                if(a[2]==b[2]&&a[3]==1&&(a[0]>13)||(a[0]==12&&a[1]>30))           //今天刚好周日
                Ao=true;
                if(a[2]>=(b[2]+7)%366) {Ao=true;ao=true;}                                 //超过七天未更新
                if(a[3]<b[3])   {Ao=true; ao=true;}                                 //两次登录时间里含有周日
                if(Ao&&ao){
                    SharedPreferences.Editor editor=getSharedPreferences("data",MODE_PRIVATE).edit();
                    editor.putInt("all_score",0);
                    editor.putBoolean("isRefresh1",false);
                    editor.apply();
模拟:第一次到达星期日的时候才会运行,Ao=true,ao=true,运行一次,ao=false,不在运行,那么问题来了,如果七天内曾打开软件,ao=false恒成立,我们就永远无法更新每周任务,所以我们要在每日任务里添加一句话在if(Bo&&bo),那就是
 editor.putBoolean("isRefresh1",true);
有什么用?每天运行了一次每日任务,就把ao=true,而只有周日12:30以后才会执行每周任务(只有这种状态需要ao的改变),这样我们就完美解决了这个问题。好了,关于每日每周自动定时更新就说完了,或许存在时间不精确的问题,但是大概的功能实现了。关于这个软件算是彻底告一段落了,一个月后将会开始新的征程,相信又会有很多新的收获和挑战!



猜你喜欢

转载自blog.csdn.net/qq_37820491/article/details/80221441