Android 系統服務和應用服務的區別

啓動方式的區別

系統服務的啓動

系統服務大部分跑在system server裏,也是在它裏面啓動的, 在system server啓動時順便把服務都啓動了如AMS ,WMS,PMS都在system server裏面html

private void run(){
    ...
    startBootstrapService();
    startCoreService();
    startOtherServices();
    ...
}
複製代碼
  • 啓動服務不必定是要啓動工做線程,其實大部分服務都是跑在binder線程的,少部分纔有本身的工做線程。 因此啓動服務是什麼意思?主要是作服務的init工做,如準備服務的binder實體對象, 當client有請求,就會在binder線程池裏把請求分發給對應的binder實體對象處理,再回復給clientjava

  • 還有一些服務不在system server裏面,它本身開了一個進程, 這種服務通常是native實現的,有本身的main入口函數,須要本身啓用binder機制,管理binder通訊,複雜一些, 可是同樣的,它也要有binder實體對象,binder線程,binder線程等待client請求,再分發給binder實體對象。面試

應用服務的啓動

不管是start service,仍是bind service,都是從應用端發起的 請求會調到AMS裏面。bash

ComponentName startServiceCommon(...){
    ....
    //拿到AMS的binder對象,startSetvice是IPC調用,它裏面會建立ServiceRecord,
    //ServiceRecord只是service的記錄,AMS只是負責service的管理和調度,service的啓動和加載仍是要在應用端作的
    ActivityManagerNative.getDefault().startService(...);
}
複製代碼

應用端怎麼啓動和加載serviceapp

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();
}
複製代碼

註冊方式的區別

系統服務的註冊

//跑在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));
}
複製代碼
  1. 不管是在sysemserver進程,仍是單獨進程,都要在service manager註冊服務。ide

  2. 應用端的binder實體對象註冊到service manager,確定提示權限錯誤,由於只有系統服務能夠註冊到service mananger。函數

應用服務的註冊

  1. 應用端向AMS發起binderService調用,
  2. AMS看service註冊過沒有,註冊過直接把binder的service對象返回給應用。
  3. 若沒有,AMS去請求binder對象,Service響應請求,把本身的binder對象註冊到AMS,AMS再把binder對象回調給應用端。

使用方式的區別

系統服務的使用

//經過context的getSystemService(),傳入名字,查到服務的管理對象
PowerManager pm  = context.getSystemService(Context.POWER_SERVICE);
//調用對象的接口函數使用系統服務
PowerManagfer.WakeLock = pm.newWakelock(Flags. TAG);
複製代碼

SystemServiceRegistry.javaui

獲取系統服務
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);
    }
})
複製代碼

參考

相關文章
相關標籤/搜索