만일 항상 떠있는 서비스를 구현하고자 하는 경우에는 이런 일이 발생하는것에 대해 아주 당황할것이다.
이럴경우 서비스를 죽지 않도록 하고자 할것인데.
이런 경우 알람서비스를 이용하여 서비스가 죽으면 다시 살리는 방법이 있다.
많은 경우 이런 방식을 이용하는것으로 보인다.
PersistentService가 죽지 않아야 할 서비스이다. 아래 예제에서 보면 onCreate시 기존 알람이 있으면 제거하고 onDestroy시 알람을 기동한다.
알람은 일정시간이 지나면 PendingIntent를 날리는 알람이며 이 인텐트를 받을 수 있는 BroadcastReceiver가 있게 된다. 여기서는 RestartService receiver가 해당 인텐트를 받아서 이 때 종료된 PersistentService를 재기동 시키는 역할을 한다.
PersistentService.java
class PersistentService extends Service {
onCreate(..) {
unregisterRestartAlram(); //이미 등록된 알람이 있으면 제거
}
onDestroy(..) {
registerRestartAlram(); // 서비스가 죽을때 알람을 등록
}
// support persistent of Service
void registerRestartAlarm() {
Log.d(TAG, "registerRestartAlarm");
Intent intent = new Intent(PersistentService.this, RestartService.class);
intent.setAction(RestartService. ACTION_RESTART_PERSISTENTSERVICE);
PendingIntent sender = PendingIntent.getBroadcast(PersistentService.this, 0, intent, 0);
long firstTime = SystemClock.elapsedRealtime();
firstTime += 10*1000; // 10초 후에 알람이벤트 발생
AlarmManager am = (AlarmManager)getSystemService( ALARM_SERVICE);
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP , firstTime, 10*1000, sender);
}
void unregisterRestartAlarm() {
Log.d(TAG, "unregisterRestartAlarm");
Intent intent = new Intent(PersistentService.this, RestartService.class);
intent.setAction(RestartService. ACTION_RESTART_PERSISTENTSERVICE );
PendingIntent sender = PendingIntent.getBroadcast(PersistentService.this, 0, intent, 0);
AlarmManager am = (AlarmManager)getSystemService( ALARM_SERVICE);
am.cancel(sender);
}
}
RestartService.java
public class RestartService extends BroadcastReceiver {
public static final String ACTION_RESTART_PERSISTENTSERVICE = "ACTION.Restart. PersistentService";
@Override
public void onReceive(Context context, Intent intent) {
Log.d("RestartService", "RestartService called!@!@@@@@#$@$@#$@#$@#");
if(intent.getAction().equals(ACTION_RESTART_PERSISTENTSERVICE)) {
Intent i = new Intent(ctx, PushService.class);
context.startService(i);
}
}
manifest.xml
<application android:icon="@drawable/icon" android:label="@string/app_name" >
<receiver android:name="RestartService" android:process=":remote"/>