后台执行的定时任务
Android中实现定时任务一般有两种机制,一种是Alarm,具有唤醒CPU的功能,
可以保证每次需要执行任务的时候CPU都能正常工作,而Timer则不能唤醒CPU。
Alarm机制的用发
-
创建一个LongRunningService类继承Service,重写onStartCommand方法。
public class LongRunningService extends Service { @Override public IBinder onBind(Intent intent) { return null; } @Override public int onStartCommand(Intent intent, int flags, int startId) { return super.onStartCommand(intent, flags, startId); } }
-
在onStartCommand方法中创建一个线程
new Thread(new Runnable() { @Override public void run() { //写执行的具体逻辑,这里为了方便直接打印log Log.i(TAG, "run: executed at "+new Date().toString()); } }).start();
-
在onStartCommand方法中创建一个AlarmManager实例
AlarmManager manager = (AlarmManager) getSystemService(ALARM_SERVICE);
-
调用manager.set(int type, long triggerAtMillis, PendingIntent operation)方法。
int anHour = 60*1000; long triggerAtTime = SystemClock.elapsedRealtime()+anHour; Intent i = new Intent(this,AlarmReceiver.class); PendingIntent pi = PendingIntent.getBroadcast(this,0,i,0); manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,triggerAtTime,pi);
下面简单讲一下set方法的三个参数
- 第一个参数是整形参数,用来指定AlarmManager的工作类型
- ELAPSED_REALTIME表示让定时任务的触发时间从系统开机开始算起,但不会唤醒CPU。
- ELAPSED_REALTIME_WAKEUP同上,但是会唤醒CPU。
- RTC表示让定时任务的触发时间从1970年1月1日0点开始算起,但不会唤醒CPU。
- RTC_WAKEUP同上,但是会唤醒CPU。
- 第二个参数用来指定定时任务触发的时间,单位为毫秒。
- 如果第一个参数使用ELAPSED开头的参数就传入开机至今的时间加上延迟执行的时间。
- 如果第一个参数使用RTC开头的参数就传入1970年1月1日0点至今的时间加上延迟执行的时间。
- 使用SystemClock.elapsedRealtime()方法可以获取到系统开机至今所经历时间的毫秒数。
- 使用System.currentTimeMillis()方法可以获取到1970年1月1日0点至今所经历时间的毫秒数。
- 第三个参数是PendingIntent,用于指定一个未执行的意图。
- 通过getBroadcast()方法获取一个能够执行广播的PendingIntent,当定时任务被触发时执行广播。
-
创建一个AlarmReceiver类继承BroadcastReceiver,并重写onReceive方法。
public class AlarmReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Intent i = new Intent(context, LongRunningService.class); context.startService(i); } }
- 当广播执行onReceive方法时,启动LongRunningService服务以完成无限循环。
-
在MainActivity的onCreate方法中启动服务。
Intent intent = new Intent(this, LongRunningService.class); startService(intent);
-
在Manifest文件中注册BroadcastReceiver和Service
<receiver android:name=".AlarmReceiver"> </receiver> <service android:name=".LongRunningService"/>