对于RemoteService的一些问题小结。
1. 为什么service ondestroy后还在,因为servicedestroy后系统有一个策略是保存service,大概占内存5M(可以开启一个新进程只有service看出),方便快速下次启动。
2. 如果要自己释放这个内存,如果是跨进程的,那么必须杀进程。但是,service如果是异常结束的,那么系统会自动重新掉起service(异常恢复),disconnection->service connection->service oncreate->service onbind。为了系统不重新启动service,我们的办法是,先unbindService->kill process
3. 对于service connection 与 service disconnection时机
我们知道bind一个service成功后会回调service connection。但是unbind这种正常结束service的情况是不会调用service disconnection的,什么时候会掉disconnection呢?
a. service所属进程被意外杀死(前提没有正常unbind)
b.service所属进程有crash造成崩溃
4. 关于生命周期的几个方法onStop能关闭service吗?
a. bind--->unbind :service create-> bind-> unbind-> destroy
b. bind--->start: service create->bind->startcommand->start
c. bind--->start--->start: service create->bind->startcommand->start->startcommand->start
d. bind->start->bind->bind 和b相同
e. bind-->start-->stop: service create->bind->startcommand->start
e. bind-->start-->stop-->unbind: service create->bind->startcommand->start->unbind->ondestroy
f. bind-->start-->unbind: service create->startcommand->start->unbind
g. bind-->start-->unbind-->stop:service create->startcommand->start->unbind-->ondestroy
从上面可以看出只要是bind的service是不能通过stop来销毁service的,stop作用并不明显,而且bind只会bind一次,但是startservice却可以调用很多次,在销毁的时候如果只是bind,则可以通过unbind就可以让servicedestroy,但是如果service启动时同时调用了bind和start,则结束service必须同时用unbind和stop
5. deadobject
我们程序中进程会出现这个问题,问题原因是拿了已经销毁service对应的aidl引用。比如service被我们强制杀死,如果执行了unbind和kill。但是没有将aidl引用制成null的话,因为我们bindservice往往是双向持有对方的aidl,下次使用这个aidl的时候就会报deadobject。解决办法就是在service解除绑定的时候也将持有service的aidl引用制成null。每次使用的时候去判空,确定是重新bind或者其他。
6. 在aidl调用过程中,比如A调用Bservice,用aidl调用方法killService()。作用就是去杀B进程。这个问题就是在回调过程杀进程,首先杀进程的方法复习一下,就是unbind+kill process。但是因为是在aidl方法中,直接杀进程,会让aidl直接报异常deadobject,方法没有返回,所以要将unbindkill process的动作延迟进行,post delay或者 开线程,并且要sleep