寫給Android App開發人員看的Android底層知識(5)

     (十)Servicespa

     Service有兩套流程,一套是啓動流程,另外一套是綁定流程。咱們作App開發的同窗都應該知道。插件

 

     

     1)在新進程啓動Service3d

       咱們先看Service啓動過程,假設要啓動的Service是在一個新的進程中,分爲5個階段:對象

       1)App向AMS發送一個啓動Service的消息。blog

       2)AMS檢查啓動Service的進程是否存在,若是不存在,先把Service信息存下來,而後建立一個新的進程。進程

       3)新進程啓動後,通知AMS說我能夠啦。ssl

       4)AMS把剛纔保存的Service信息發送給新進程ci

       5)新進程啓動Service開發

 

     咱們仔細看一下這5個階段:it

 

     第1階段

 

     

 

     和Activity很是像,仍然是經過AMM/AMP把要啓動的Service信息發送給AMS。

 

     第2階段

     AMS檢查Service是否在Manifest中聲明瞭,沒聲明會直接報錯。

 

     AMS檢查啓動Service的進程是否存在,若是不存在,先把Service信息存下來,而後建立一個新的進程。

 

     在AMS中,每一個Service,都使用ServiceRecord對象來保存。

 

     第3階段

     Service所在的新進程啓動的過程,就和前面介紹App啓動時的過程差很少。

 

     新進程啓動後,也會建立新的ActivityThread,而後把ActivityThread對象經過AMP傳遞給AMS,告訴AMS,新進程啓動成功了。

 

     第4階段

     AMS把傳進來的ActivityThread對象改造爲ApplicationThreadProxy,也就是ATP,經過ATP,把要啓動的Service信息發送給新進程。

 

     第5階段

 

     

 

     新進程經過ApplicationThread接收到AMS的信息,和前面介紹的啓動Activity的最後一步相同,藉助於ActivityThread和H,執行Service的onCreate方法。在此期間,爲Service建立了Context上下文對象,並與Service相關聯。

 

     須要重點關注的是ActivityThread的handleCreateService方法,

 

     

 

     你會發現,這段代碼和前面介紹的handleLaunchActivity差很少,都是從PMS中取出包的信息packageInfo,這是一個LoadedApk對象,而後獲取它的classloader,反射出來一個類的對象,在這裏反射的是Service。

     四大組件的邏輯都是如此,因此咱們要作插件化,能夠在這裏作文章,換成插件的classloader,加載插件中的四大組件。

 

     至此,咱們在一個新的進程中啓動了一個Service。

 

    2)啓動統一進程的Service

     若是是在當前進程啓動這個Service,那麼上面的步驟就簡化爲:

       1)App向AMS發送一個啓動Service的消息。

       2)AMS例行檢查,好比Service是否聲明瞭,把Service在AMS這邊註冊。AMS發現要啓動的Service就是App所在的Service,就通知App啓動這個Service。

       3)App啓動Service。

 

     咱們看到,沒有了啓動新進程的過程。

 

    3)在同一進程綁定Service

     若是是在當前進程綁定這個Service呢?過程是這樣的:

       1)App向AMS發送一個綁定Service的消息。

       2)AMS例行檢查,好比Service是否聲明瞭,把Service在AMS這邊註冊。AMS發現要啓動的Service就是App所在的Service,就先通知App啓動這個Service,而後再通知App,對Service進行綁定操做。

       3)App收到AMS第1個消息,啓動Service,

       4)App收到AMS第2個消息,綁定Service,並把一個Binder對象傳給AMS

       5)AMS把接收到的Binder對象,發送給App

       6)App收到Binder對象,就可使用了。

 

     你也許會問,都在一個進程,App內部直接使用Binder對象不就行了,其實吧,要考慮不在一個進程的場景,代碼又不能寫兩份,兩套邏輯,因此就都放在一塊兒了,即便在同一個進程,也要繞着AMS走一圈。

 

    第1階段:App向AMS發送一個綁定Service的消息。

 

     

 

     第4階段:處理第2個消息

 

     

     第5階段和第6階段:

 

     這一步是要仔細說的,由於AMS把Binder對象傳給App,這裏沒用ATP和APT,而是用到了AIDL來實現,這個AIDL的名字是IServiceConnection。

 

     

 

     ServiceDispatcher的connect方法,最終會調用ServiceConneciont的onServiceConnected方法,這個方法咱們就很熟悉了。App開發人員在這個方法中拿到connection,就能夠作本身的事情了。

 

      好了,關於Service的底層知識,咱們就全都介紹完了。當你再去編寫一個Service時,是否感受對這個組件理解的更透徹了呢?

 

     下一篇咱們聊一聊BroadcastReceiver。

相關文章
相關標籤/搜索