zoukankan      html  css  js  c++  java
  • Android Framework 学习(二):系统服务与应用服务

    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);
        }
    })
  • 相关阅读:
    延时函数出错,volatile一例
    【转】STM32中的抢占优先级、响应优先级概念
    【转载】串口中怎样接收一个完整数据包的解析
    ARM-ContexM3/4组优先级和子优先级抢占规则
    【转载】Keil中的USE MicroLib说明
    线程让出实验【RT-Thread学习笔记 4】
    线程优先级抢占实验【RT-Thread学习笔记 3】
    RT-Thread的线程(任务)处理【RT-Thread学习笔记 2】
    熟悉RT-Thread的软硬件环境【RT-Thread学习笔记 1】
    RT-Thread下的串口驱动程序分析【转载】
  • 原文地址:https://www.cnblogs.com/renhui/p/12889077.html
Copyright © 2011-2022 走看看