我在使用KitKat时发现了几篇关于return_sticky问题的帖子。
似乎服务可以被杀死,即使在return_sticky时也不会回来。
我说的是后台服务,而不是前台服务。
我尝试了几种方法,但一切似乎都失败了。下面是一些演示代码。过了一会儿就被杀了,它不会再回来了:
public class RestPushService extends Service {
@Override
public void onDestroy() {
MainApplication.getDevice().writeBoolean("REST_PUSHSERVICE_RUNNING", false);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
if ((intent != null) && (intent.getBooleanExtra("ALARM_RESTART_SERVICE_DIED", false))) {
if (MainApplication.getDevice().readBoolean("REST_PUSHSERVICE_RUNNING", false)){
ensureServiceStaysRunning();
return START_STICKY;
}
}
MainApplication.getDevice().writeBoolean("REST_PUSHSERVICE_RUNNING", true);
/** doing other stuff like creating a thread **/
return START_STICKY;
}
private void ensureServiceStaysRunning() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
final int restartAlarmInterval = 20 * 60 * 1000;
final int resetAlarmTimer = 2 * 60 * 1000;
final Intent restartIntent = new Intent(this, RestPushService.class);
restartIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
restartIntent.putExtra("ALARM_RESTART_SERVICE_DIED", true);
final AlarmManager alarmMgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Handler restartServiceHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
PendingIntent pintent = PendingIntent.getService(getApplicationContext(), 0, restartIntent, 0);
alarmMgr.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + restartAlarmInterval, pintent);
sendEmptyMessageDelayed(0, resetAlarmTimer);
}
};
restartServiceHandler.sendEmptyMessageDelayed(0, 0);
}
}
@Override
public void onTaskRemoved(Intent rootIntent) {
Intent restartService = new Intent(getApplicationContext(), this.getClass());
restartService.setPackage(getPackageName());
PendingIntent restartServicePI = PendingIntent.getService(getApplicationContext(), 1, restartService, PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmService = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
alarmService.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + 1000, restartServicePI);
}
}
现在另一个接收器在设备启动时被调用。
public class myReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action == null || action.equals("com.myapp.START_ALARM")) {
if (MainApplication.getDevice().hasInternet()) {
if (!MainApplication.getDevice().hasServiceRunning(RestPushService.class)) {
context.startService(new Intent(context, RestPushService.class));
} else {
Log.d(TAG, "RestPushService was aready running. Do nothing");
}
}
}
}
public void startRepeating(Context context) {
if (alarmManager == null) alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent("com.myapp.START_ALARM");
PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000 * 60 * 30, pi); // Millisec * Second * Minute
}
public void stopRepeating(Context context) {
Intent intent = new Intent("com.myapp.START_ALARM");
PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
alarmManager.cancel(sender);
}
}
我已经截断了很多代码,因为我觉得它不相关。我删除了所有try catch和null初始化,以确保它易于阅读。那么可能导致“不会回来”的原因是什么?废话?