当前位置: 代码迷 >> 综合 >> AlarmManager, WakeLock and IntentService
  详细解决方案

AlarmManager, WakeLock and IntentService

热度:30   发布时间:2023-12-17 21:58:15.0

在Android开发中,我们经常会用到AlarmManager来做一些类似于Linux cron job的工作。我们以下面的代码为例来说明整个流程:


1
2
3
4
5
6
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, WakeUpDemoReceiver. class );
i.setAction( "WakeUpDemo" );
PendingIntent pi =
             PendingIntent.getBroadcast(context, "WakeUpDemo" , i, 0 );
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 100000 , pi);


上面的代码说明了AlarmManager在定时时间到了之后会广播一个Intent出来。这个Intent将会被一个 BroadcastReceiver 的实现类来处理:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class WakeUpDemoReceiver extends BroadcastReceiver {
     @Override
     public void onReceive(Context context, Intent intent) {
         String action = intent.getAction();
         if ( "WakeUpDemo" .equals(action)) {
             WakeLockManager lock = WakeLockManager.getInstance(context);
             lock.acquire();
             Intent demo = new Intent( "DemoService" );
             eventIn.setClass(context, DemoIntentService. class );
             context.startService(demo);
         }
     }
}


这里引入了WakeLockManager。当定时时间到了之后,Android系统会被AlarmManager唤醒,然后通过Intent传递到WakeUpDemoReceiver。这里为什么要用WakeLock?原因在于我们在onReceive方法里面启动了一个DemoIntentService。我们一般把一些耗时的工作放到了这个DemoIntentService里面去执行。如果不在onReceive开始的时候加锁,系统有可能在启动DemoIntentService之前重新在进入睡眠状态。

一旦我们获取了锁,那么CPU就会处于running的状态,如果不尽快的释放锁,那么对电源的消耗是非常大的。那么我们应该在什么地方释放那?在DemoIntentService里面。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public class DemoIntentService extends IntentService {
     
     public DemoIntentService (String name) {
         super (name);
     }
     @Override
     public void onCreate() {
         super .onCreate();
     }
     @Override
     public void onDestroy() {
         WakeLockManager lock = WakeLockManager.getInstance( this );
         lock.release();
         super .onDestroy();
     }
     
     @Override
     public IBinder onBind(Intent arg0) {
         return null ;
     }
     
     @Override
     public int onStartCommand(Intent intent, int flags, int startId) {
         super .onStartCommand(intent, flags, startId);
         return (START_REDELIVER_INTENT);
     }
     @Override
     protected void onHandleIntent(Intent intent) {
         handleIntent(intent);
     }
}


当DemoIntentService处理完Intent事件之后就会调用onDestroy,这样就保证了我们自己的逻辑工作做完之后立刻释放锁。

WakeLockManager是一个简单的WakeLock的包装类。这里就不在说明。

下面的几个链接可以帮助我们从其他的角度来理解上面所说的流程。

http://www.androidguys.com/2009/04/02/wake-up-with-the-alarm/

http://stackoverflow.com/questions/7665713/whats-the-best-between-alarmmanager-and-handlerwakelock

https://github.com/commonsguy/cw-advandroid/tree/master/SystemServices/Alarm