启动服务是有两组参数影响服务的状态。

1、在onStartCommand(Intent intent, int flags, int startId) 接口中返回值例如 START_STICKY; 表明开关计数不为0,表明服务如果被意外Kill掉(例如从DDMS中杀掉)服务会重新启动。

2、在bindService(Intent  int flags)中的最后一个参数, 例如Context.BIND_AUTO_CREATE,表明如果引用数不为0,服务如果被意外杀掉服务将重启。

onStartCommand在客户端Start调用后被回调,表明服务自身定义的声明周期,是希望长周期运行还是用完即止。 而BindService是在客户端调用,表明了客户端希望服务在数据通信中的状态,是可靠连接还是不可靠连接。

     因此服务销毁的条件也相应拥有两个层面的条件, 

1、在服务层面从Start - Stop为一个完整的周期,Stat ()开关计数+1 Stop开关计数-1,引用数=0 表明系统可以销毁服务了。Stop必须被明确调动,开关计数才减1,客户端进程退出不影响服务端的开关计数,(这里解释了为什么应用都杀掉了,为什么服务还是杀不掉);

2、在客户端层面,Bind 到 UnBind是一个周期,Bind 连接计数+1,UnBind连接计数-1.  连接计数为0,系统即可销毁服务了。 与Start和Stop计数不同, 调用服务的线程被销毁,连接计数-1. (这里解释了为什么应用服务的程序被kill掉后,kill Bind创建的服务可以杀掉)

3、同时满足上述两个条件。服务才被销毁。

 

     正以上原因,解释了为什么,在Android 程序管理器中停止服务,然后在后台进程管理中杀掉服务进程,才能真正停止Start_STICKY的进程。终止服务实际上是将计数清零。

 

     从DDMS看看微信在后台运行的两个进程com.tencent.mm(应用服务)和com.tentcent.mm:push(推送服务)

      1、push推送服务进程能够独立运行, 而且被DDMS kill后会重新启动,应该是mm用Start方式创建的一个service,

      2、mm与push进程差不多,被DDMS kill后会重新启动,mm在总的运行时间上看比push时间短,应该是push启动它后,完成任务就stop退出了(或者stopself)。

     3、如果把mm和push的服务彻底停掉(从Android的服务管理器中),过几分钟后 push进程先恢复,然后mm再启动。(进程如何恢复,应该是使用了Alarmanger的机制,定期唤醒服务。)

     通过上述表现,可以分析push应该是一个保持基本连接通信的线程,内存消耗较小。腾讯的通信如果用的不是HTTP协议,就需要进程保持通信的长连接。mm应该是具体的数据处理和业务管理的,内存消耗较大。