Service的工作过程

147 阅读2分钟

「这是我参与2022首次更文挑战的第6天,活动详情查看:2022首次更文挑战」。

Service的创建过程

Intent intentService = new Intent(this,MyService.class);
startService(intentService);

首先看一个关系图

image.png

Service一般是在Activity中创建的,创建方式有两种:startService与bindService,这两种方式在功能上的区别是startService一般用于后台计算,bindService用于其他组件与其交互,Activity之所以可以startService或者bindService是因为其继承来自ContenxtWrapper,而ContenxtWrapper包含一个ContextIml,ContextIml具体实现了Context的功能\

startService

和之前Activity的创建过程一样,当调用Context的startService时,其实也是通过AMS的远程代理来通知AMS来进行startService,但是AMS本身不会去管理Service的创建,而是通过一个mServices(AcitiveServices类的对象)去对Service的创建过程的参数进行一定的加工,检测,记录( SeviceRecord)在执行完这些操作后,最终和Activity的创建一样,通过获得app进程的Binder,来通知原进程进行Service的创建,同样,当到达原进程后又会通过Handler来完成service的创建,接着Service attach一个conTextImpl,最后调用onCreate方法,将Service添加到ActivityThread(UI线程)的一个列表中,这个列表记录了Binder和Service的对应关系

Service的绑定过程

Intent intentService = new Intent(this,MyService.class);
bindService(intentService,mServiceConnection,BIND_AUTO_CREATE);

首先Service的绑定过程一定先会创建一个Service,这个过程和之前startService类似,这里主要说一下bindService的过程,同样的,最初也是通知AMS来完成Service的绑定,AMS会回调ApplicationThread(该ApplicationThread是Service所在的进程拥有的)中的scheduleBindService方法,同样也会中转给handler,在handler中会根据Service的token从而取得Service再通过onBind方法将一个Binder交给AMS,AMS最终再交给客户端。
在这之前需要在一个ArrayMap中将ServiceConnection与ServiceDispather相映射起来,ServiceDispather中有个InnerConnection,这是一个IBinder,ServiceConnection最终会转换成InnerConnection,以便跨进程服务最终可以通过这个InBinder将服务的Binder传给客户端。