1. 启动方式的区别
系统服务启动:系统服务大部分跑在system server里,一般都是在system server里面启动的,在system server启动时顺便把服务都启动了如AMS,WMS,PMS都在system server里面。
private void run(){
...
startBootstrapService();
startCoreService();
startOtherServices();
...
}
应用服务启动:无论是start service,还是bind service,都是从应用端发起的请求会调到AMS里面。
ComponentName startServiceCommon(...){
....
//拿到AMS的binder对象,startSetvice是IPC调用,它里面会创建ServiceRecord,
//ServiceRecord只是service的记录,AMS只是负责service的管理和调度,service的启动和加载还是要在应用端做的
ActivityManagerNative.getDefault().startService(...); }
应用端启动和加载Service的方式如下:
private void handleCreateService(CreateServiceData data) {
//通过loadClass加载service的类,newInstance给service创建对象
Service service = (Service)cl.loadClass(data.info.name).newInstance(); //给service创建上下文 ContextImpl context = ContextImpl.createAppContext(this, ..); //create application Application app = packageInfo.makeApplication(false, ...); //attach service service.attach(context, this, ...); //执行声明周期回调 service.onCreate(); }
2. 注册方式的区别
系统服务的注册
//跑在system server进程,java层实现
pubic void setSystemProcess(){
ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); ... } //跑在单独进程,native层实现 int main(int, char**){ sp<IServiceManager> sm(defaultServiceManager()); sm->addService(String16(SurfaceFlinger::getServiceName(), flinger, false)); }
无论是在sysemserver进程,还是单独进程,都要在service manager注册服务。
应用端的binder实体对象注册到service manager,肯定提示权限错误,因为只有系统服务可以注册到service mananger。
应用服务的注册
应用端向AMS发起binderService调用,
AMS看service注册过没有,注册过直接把binder的service对象返回给应用。
若没有,AMS去请求binder对象,Service响应请求,把自己的binder对象注册到AMS,AMS再把binder对象回调给应用端。
3. 使用方式的区别
系统服务的使用
//通过context的getSystemService(),传入名字,查到服务的管理对象
PowerManager pm = context.getSystemService(Context.POWER_SERVICE);
//调用对象的接口函数使用系统服务
PowerManagfer.WakeLock = pm.newWakelock(Flags. TAG);
SystemServiceRegistry.java
获取系统服务
registerService(Context.POWER_SERVICE, PowerManager.class, //先找到Service对应的serviceFetcher,再通过Fecher拿到服务的管理对象 new CachedServiceFetcher<PowerManager>(){ @Override public PowerManager createService(ContextImpl ctx){ //先通过service manager的getService函数获取系统服务的binder对象 IBinder b = ServiceManager.getService(Context.POWER_SERVICE); //用对象封装了一层服务的管理对象再传给AP层,方便应用层调用 IPowerManager service = IPowerManager.Stub.asInterface(b); return new PowerManager(ctx.getOuterContext(),..); } });
应用服务的使用
bindService(serviceIntent, new ServiceConection(){
@Override
//AMS通过onServiceConnected回调,把服务的IBinder对象返回给AP端,
public void onServiceConnected(ComponentName name, IBinder service){ //把binder对象service封装一层业务接口对象,就可以持有对象向AP服务发起调用了 IMyInterface myInterface = IMyInterface.Stub.asInterface(service); } })