android四大组件启动流程 - Service启动流程

时间:2021-06-09 22:08:03
转载请注明出处:http://blog.csdn.net/newhope1106/article/details/53843809 前面已经提过Activity的启动流程,有兴趣的可以查看:http://blog.csdn.net/newhope1106/article/details/53355189,里面主要都是代码流程。 Service启动有2种方式,一种是startService,一种是bindService,两者目的不一样,前者是做长时间的后台操作(比如下载,播放音乐),后者主要是完成交互,前者的需要调用stopService或者stopSelf来停止,生命周期和调用者无关,而后者生命周期一般和调用者(Activity)是一致的,当调用者destroy之后,Service会解除绑定,如果所有的绑定都解除,才会退出。当然有一种特殊情况下,一个Service同时被startSerive和bindService调用过,只有两者的结束条件都被调用了,才会退出,如播放音乐的时候,调用过startService,然后想交互的时候,又调用了bindService,则需要调用stopService(或stopSelf)和unbindService才会退出。 (1)startService方式启动service流程

在Activity启动的流程中有一个attach方法调用,下面看看关键的代码:

Context appContext = createBaseContextForActivity(r, activity);
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config = new Configuration(mCompatConfiguration);
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
+ r.activityInfo.name + " with config " + config);
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor);

上述的createBaseContextForActivity生成的其实是ContextImpl这个类,因此在调用startService实际上是ContextImpl来调用的。 下面是startService的调用流程:
ContextImpl.startService(...)

ContextImpl.startServiceCommon(...)

ActivityManagerService.startService(...)

ActiveServices.startServiceLocked(...)

ActiveServices.startServiceInnerLocked(...)

ActiveServices.bringUpServiceLocked(...)

ActiveServices.realStartServiceLocked(...)

ActivityThread.ApplicationThread.scheduleCreateService(...)

ActivityThread.H.handleMessage(CREATE_SERVICE)

ActivityThread.handleCreateService(...)

Service.attach(...)

Service.onCreate(...)

ActiveServices.sendServiceArgsLocked(...)

ActivityThread.ApplicationThread.scheduleServiceArgs(...)

ActivityThread.H.handleMessage(SERVICE_ARGS)

ActivityThread.handleServiceArgs(...)

Service.onStartCommand(...)
以上是startService的启动流程,和Activity的流程基本类似,由startService方法开始,然后跨进程调用AMS,AMS再扔给对应的类来处理,AMS基本上像一个桥接器一样,但是真正实现里面复杂逻辑的不是AMS,而是由相应的功能类来处理。比如Service是由ActiveServices来管理的。上述只列出基本方法调用流程,可以清楚的看到Service的生命周期的2个方法onCreate、onStartCommand。
(2)bindService方式启动service流程
ContextImpl.bindService(...)

ContextImpl.bindServiceCommon(...)

ActivityManagerService.bindService(...)

ActiveServices.bindServiceLocked(...)

ActiveServices.bringUpServiceLocked(...)

ActiveServices.realStartServiceLocked(...)

ActivityThread.ApplicationThread.scheduleCreateService(...)

ActivityThread.H.handleMessage(CREATE_SERVICE)

ActivityThread.handleCreateService(...)

Service.attach(...)

Service.onCreate(...)

ActiveServices.requestServiceBindingLocked(...)

ActivityThread.ApplicationThread.scheduleBindService(...)

ActivityThread.H.handleMessage(BIND_SERVICE)

ActivityThread.handleBindService(...)

Service.onBind(...)

ActivityManagerService.publishService(...)
上述是bindService的过程,包含了2个生命周期方法onCreate、onBind,所不同的是bindServiceCommon中,会把客户端的ServiceConnection对象转化为ServiceDispatcher.InnerConnection对象。因为很多时候Service会被用于远程服务,提供一个公开的接口,供连接的客户端调用(C/S模式),此时是跨进程调用,因此需要借助于binder才能让远程服务端回调自己的方法,而ServiceDispatcher的内部类InnerConnection就充当Binder这个角色。这个过程是LoadedApk的getServiceDispatcher方法来完成的。
以上是Service的2种启动方式,其实终止和解绑的过程都差不过类似。 注:service被多次startService,只需要一次stopService就可以结束,但是被多次bindService则需要全部unbindService才结束。