一、Service的启动方式
Service的启动方式主要是:startService、bindService。
binderService和startService的区别:
binderService不会触发应用端的onStartCommand函数。
二、startService的流程
流程分为两部分:AMS端、应用端。
AMS的流程:
1). 先看Service启动了没有:如果启动了就直接发指令,让应用端执行onStartCommand()。
2). 如果Service没有启动,就看它所在进程启动了没有:如果已经启动,就去启动Service,等Service启动了之后再发送指令让其执行onStartCommand。
3). 如果进程没有启动就去启动进程,等进程启动后再启动Service。
应用端的流程:
1). 先创建Service对象
2). 再赋予上下文
3). 最后调用生命周期onCreate()
startService启动过程的参与者和通信过程:
参与者和通信过程可以结合下图来进行梳理和理解:
三、bindService的流程
首先bindService的用法如下:
//1.首先要定义一个AIDL接口: IRemoteCaller mCaller; ServiceConnection mServiceConnection = new ServiceConnection(){ //3.绑定成功后会收到onServiceConnected回调 @Override public void onServiceConnected(ComponentName name, IBinder service){ //4.根传进来的binder对象封装成一个业务层的接口对象 mCaller = IRemoteCaller.Stub.asInterface(service); //5.用这个对象向Service发起调用 mCaller.call(); } ... }; //2.应用端调用bindService进程绑定 Intent service = new Intent(this, MyService.class); bindService(service, mServiceConnection, BIND_AUTO_CREATE);
bindService流程如下图所示:
根据上图,概况Binder流程如下:
- 应用向AMS发起bindService调用。
- AMS首先检查有没有Service的binder句柄,如果有就直接把它回调给应用。
- 如果没有,AMS就会向Service请求binder句柄。
- Service收到之后就会把自己的binder句柄发布到AMS。
- AMS再把这个binder句柄回调给应用。
- 应用拿到这个binder句柄后就可以向Service发起binder调用了。