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); } })


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM