前言
最近碰到了一个空指针异常。崩溃日志表示Intent为空,导致下面代码崩溃:
intent.getBooleanExtra("keyfrom", false);
Intent对象是在每次启动Service的时候都会传递过去的,正常来说,这个Intent对象是不可能为空的。
代码分析
分析代码后发现,onStartCommand方法有一个地方设置flag,代码中设置的值为ServiceSTART_STICKY
,这个值的意思是Service所在的进程如果被kill了,这个Service有可能被系统重启。但是系统重启Service的时候,Intent对象是为空的。
网上说可以将标志位设置为Service.START_REDELIVER_INTENT
,这个标志位的意思是重启Service的时候,重新传递Intent对象。但是实践发现,并么有卵用,还是有一定概率导致崩溃。
所有的解决方法,标志位改成了Service.START_REDELIVER_INTENT
,同时在代码中进行了判空操作;双重保险。
下面附上Service常用flag及其意思:
附录
Flag | Meaning |
---|---|
START_STICKY | 如果service进程被kill掉,保留service的状态为开始状态,但不保留递送的intent对象。随后系统会尝试重新创建service,由于服务状态为开始状态,所以创建服务后一定会调用onStartCommand(Intent,int,int)方法。如果在此期间没有任何启动命令被传递到service,那么参数Intent将为null。 |
START_NOT_STICKY | 使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统不会自动重启该服务。 |
START_REDELIVER_INTENT | 重传Intent。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。 |
START_STICKY_COMPATIBILITY | START_STICKY的兼容版本,但不保证服务被kill后一定能重启。 |