您的位置:首页 > 移动开发 > Android开发

Android实现后台每日定时更新操作实现知识点和思路

2016-03-06 15:58 447 查看
通过AlarmManager,WakefulBroadcastReceiver,IntentService实现后台每日更新操作。

AlarmManager

Android系统级别的提示服务,可以设置在特定的时刻为我们广播一个指定的Intent(通常使用Intent加上如startActivity、startService或sendBroadcast等指定动作封装包的PendingIntent)

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


AlarmManager常用的方法:

设置一次性闹钟set(int type,long startTime,PendingIntent pi)

设置重复闹钟setRepeating(int type,long startTime,long intervalTime,PendingIntent pi);

设置大约时间的重复闹钟setInexactRepeating(int type,long startTime,long intervalTime,PendingIntent pi);

介绍参数:
(1)int type: 闹钟的类型,常用的有5个值:
AlarmManager.RTC_WAKEUP状态值为0,表示闹钟在睡眠状态下会唤醒系统并执行提示功能,使用绝对时间;
AlarmManager.RTC状态值为1,表示闹钟在睡眠状态下不可用,使用绝对时间;
AlarmManager.ELAPSED_REALTIME_WAKEUP状态值为2,表示闹钟在睡眠状态下会唤醒系统并执行提示功能,使用相对时间;

AlarmManager.ELAPSED_REALTIME状态值为3,表示闹钟在手机睡眠状态下不可用,使用相对时间(相对于系统启动开始);
AlarmManager.POWER_OFF_WAKEUP状态值为4,表示闹钟在手机关机状态下也能正常进行提示功能,使用绝对时间;不过本状态受SDK版本影响,某些版本并不支持;
(2)long startTime: 闹钟的第一次执行时间,以毫秒为单位,可以自定义时间。
需要注意的是,本属性与第一个属性(type)密切相关,
如果第一个参数对 应的闹钟使用的是相对时间(ELAPSED_REALTIME和ELAPSED_REALTIME_WAKEUP),那么本属性就得使用系统启动相对时间,比如当前时间SystemClock.elapsedRealtime();
如果第一个参数对应的闹钟使用的是绝对时间 (RTC、RTC_WAKEUP、POWER_OFF_WAKEUP),那么本属性就得使用绝对时间,比如当前时间System.currentTimeMillis()。
(3)long intervalTime:对于后两个方法中表示两次闹钟执行的间隔时间,以毫秒为单位。
(4)PendingIntent pi: 绑定闹钟的执行动作,发送一个广播、启动服务等。PendingIntent是Intent的封装类。
获取启动服务的PendingIntent对象,Pending.getService(Context context, int requestCode, Intent intent, int flags);
获取发送广播的PendingIntent对象,PendingIntent.getBroadcast(Context context, int requestCode, Intent intent, int
flags);
获取启动ActivityPendingIntent对象的,PendingIntent.getActivity(Context
context, int requestCode, Intent intent, int flags)。

最后一个参数flags设置:

FLAG_CANCEL_CURRENT:如果当前系统中已经存在一个相同的PendingIntent对象,那么就将先将已有的PendingIntent取消,然后重新生成一个PendingIntent对象。
FLAG_NO_CREATE:如果当前系统中不存在相同的PendingIntent对象,系统将不会创建该PendingIntent对象而是直接返回null。
FLAG_ONE_SHOT:该PendingIntent只作用一次。在该PendingIntent对象通过send()方法触发过后,PendingIntent将自动调用cancel()进行销毁,那么如果你再调用send()方法的话,系统将会返回一个SendIntentException。
FLAG_UPDATE_CURRENT:如果系统中有一个和你描述的PendingIntent对等的PendingInent,那么系统将使用该PendingIntent对象,但是会使用新的Intent来更新之前PendingIntent中的Intent对象数据,例如更新Intent中的Extras。


WakefulBroadcastReceiver

需要<uses-permission android:name="android.permission.WAKE_LOCK"/>权限

特殊类型的广播接收器,它有startWakefulService()方法可以用来来启动IntentService,同时保证在服务启动时保持唤醒锁,通过startWakefulService()方法也可以传递保存一个额外的唤醒锁的Intent。


IntentService

Android中的Service是用于后台服务的,要强调的是Service不是独立的进程,也不是独立的线程,它依赖于应用程序的主线程(UI线程),所以在更多时候不建议在Service中编写耗时的逻辑和操作,否则会引起ANR。

当我们编写的耗时操作时可以引入IntentService,IntentService继承自Service,包含了Service的全部特性,包含service的生命周期,与service不同的,IntentService在执行onCreate操作的时候,内部开了一个新的线程,

通过protected abstract void onHandleIntent(Intent intent);执行处理所有的通过onStartCommand()传递来的intents(onHandleIntent通过识别Intent参数执行不同的任务)耗时操作。

不需要主动调用stopSelft()来结束服务,在所有的intent被处理完后,IntentService会自动停止。

默认实现的onStartCommand()的目的是将intent插入到工作队列中。

默认实现的onBind()返回null。


后台每日定时更新操作的实现思路

大致思路在主activity代码中注册一个明天的一次性闹钟,同时在intentservice执行操作前注册一个明天的一次性闹钟。闹钟的内容是启动wakefulbroadcastreceiver,在wakefulbroadcastreceiver中用startWakefulService()方法启动intentservice。同时为了防止系统重新启动未打开过应用而无法注册闹钟可以为wakefulbroadcastreceiver增加接收开机广播(<action
android:name="android.intent.action.BOOT_COMPLETED"/><uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>)。

这样一个大循环就可以顺利的运行了,除非应用被强制停止,因为强制请停止后应用注册的闹钟和广播接收器都会无效(其中广播接收器可以通过设置intent的flag从而不被忽略(intent.setFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);//程序被强制停止后可以接受广播),但是也没用闹钟已经失效了)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: