繼續研究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.
----------------------------------------------------------------------------------------------------------------------------------------------------------
這裏我要反省自己之前犯的一個錯誤,希望大家不要犯同樣的錯誤:
之前在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
- 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'sprocess
attribute can set a different default for all components. But component can override the defaultwith its ownprocess
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.
關於IPC在應用層的實現方式,我還要繼續學習下.......