關於Android Service的一些補充

繼續研究Android的官方文檔又有新的發現,現記錄如下:

        在默認的情況下,Android Service提供了一個可以在後臺運行服務,那麼這個在後臺運行的Service其實是運行在主線程(UI 線程)裏的。

         google官網對Service的解釋如下:

         

Thus a Service itself is actually very simple, providing two main features:

  • A facility for the application to tell the system about something it wants to be doing in the background (even when the user is not directly interacting with the application). This corresponds to calls to Context.startService(), which ask the system to schedule work for the service, to be run until the service or someone else explicitly stop it.
  • A facility for an application to expose some of its functionality to other applications. This corresponds to calls to Context.bindService(), which allows a long-standing connection to be made to the service in order to interact with it.
           到這裏我想反覆強調一句話,不要指望Service會在一個單獨的線程裏實例化,這個服務的回調(onCreate onDestroy)仍然會在主線程裏進行。

        

----------------------------------------------------------------------------------------------------------------------------------------------------------

這裏我要反省自己之前犯的一個錯誤,希望大家不要犯同樣的錯誤

           之前在CMMB的維護工作中,發現CMMB在啓動/退出的時候會開啓/停掉自己的相關服務MBBMSService,但是服務的退出比較耗時,會有一定的概率產生ANR。

       當時我是這樣處理這個問題的,CMMB 應用要停服務的時候會調用stopService當時我把stopService的調用放到了一個單獨線程中去做。我本來以爲這樣停止MBBMSService的操作會在一個單獨的線程中做。結果仍然有ANR,原來我這麼做並不能保證MBBMSService退出操作在一個獨立線程做。因爲調用stopService停止相應服務的時候,會回調MBBMSService中的onDestroy。在這個onDestroy在做具體的服務註銷操作(耗時),但是這個onDestroy回調仍然在主線程中做,所以無法避免anr。對於這樣的問題,應該在MBBMSService中將具體的耗時操作提出來,放到線程中做。但是這樣可能會帶來一些同步的問題,所以大家要慢慢Debug咯。


OK言歸正傳,如何讓service運行在一個新的process中呢?原來我們在AndroidManifest.xml文件中:

<service android:enabled=["true" | "false"]
         android:exported=["true" | "false"]
         android:icon="drawable resource"
         android:label="string resource"
         android:name="string"
         android:permission="string"
         android:process="string" >
    . . .
</service>
在android:process域中指定這個service所運行的進程名,以下是官網的解釋。


android:process
The name of the process where the service is to run. Normally, all components of an application run in the default process created for the application. It has the same name as the application package. The <application> element's process attribute can set a different default for all components. But component can override the defaultwith its own process attribute, allowing you to spread your application across multiple processes.

If the name assigned to this attribute begins with a colon (':'), a new process, private to the application, is created when it's needed and the service runs in that process.If the process name begins with a lowercase character, the service will run in a global process of that name, provided that it has permission to do so.This allows components in different applications to share a process, reducing resource usage.

這樣一個運行與單獨進程中Service就啓動了,既然這個Service運行與單獨的進程中,那麼和這個Service的交互過程就要使用IPC機制了。



關於IPC在應用層的實現方式,我還要繼續學習下.......





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章