我们的app经常会包含一些继承自Service或者IntentService的类。这些类的经常会用来处理系统或者app自身产生的一些Intent事件。
这是一种很方便的事件驱动模型。这里我定义了一个IntentService的子类。这个类用来接收一个由AlarmManager产生的定时事件。这个类工作的很好。直到有一天,我很惊讶的发现这个类有的时候会很诡异的不工作,或者刚开始进入处理逻辑就退出了。于是就花了一些时间去定位和寻找原因。现在原因已经基本清楚了。
先上一段代码:
public class EventService extends IntentService {
private static final String TAG = "EventService";
private PowerManager.WakeLock wl;
public SchedulerEventService(String name) {
super(name);
}
public SchedulerEventService() {
super(TAG);
}
@Override
public void onCreate() {
Log.d(TAG, " EventService onCreate.");
super.onCreate();
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "EventService");
wl.acquire();
}
@Override
public void onDestroy() {
Log.d(TAG, " EventService onDestroy.");
super.onDestroy();
wl.release();
}
@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) {
Log.d(TAG, "event received at: " + new Date().toString());
if (intent != null) {
executeTask();
}
}
}
当我的测试手机在玩一个游戏的时候,问题出来了。这个EventService在开始真正执行任务的时候:executeTask,诡异的退出来了。
最终发现了问题:当游戏的前台运行的时候,非常耗费内存。当我的APP在后台试图启动EventService的时候因为内存吃紧,被Android 系统杀死了。
这里有几个链接也说明了类似问题:
http://blog.sina.com.cn/s/blog_5731032f0101be1t.html
http://blog.youkuaiyun.com/mjm0771/article/details/6701023
解决的一个办法是对OnStartCommand方法的Override。当这个方法返回
START_REDELIVER_INTENT
的时候,系统重新启动service之后会把最后一个intent重新再传递给我们的service来处理。
如果碰到这种service被系统杀死的情况,通过这种方式可以给service一个机会重新再把最后一次没做的事情做完。