在Android系統中有很多內置的軟件,例如,當手機接到來電時,會顯示對方的電話號。也可以根據周圍的環境將手機設置成震動或靜音。如果想把這些功能加到自己的軟件中應該怎麼辦呢?答案就是“系統服務”。在Android系統中提供了很多這種服務,通過這些服務,就可以像Android系統的內置軟件一樣隨心所欲地控制Android系統了。系統服務(System Services)並非Android開發應用程序時,所涉及的Service(後臺應用服務程序,位於Android系統應用層)的概念。而是Android操作系統Java應用程序下層的,伴隨操作系統啓動而運行的系統後臺服務程序(位於Android系統的FrameWork層)。它是Android系統運行的基石,它配合binder(Android多進程通訊方法)、dalvik虛擬機和Android應用程序構成了一個多進程交互通訊,交互服務的Android系統。
Android體系架構中四種意義上服務:Native服務、Android服務、Init空間的服務、應用層空間的服務。這裏的system service屬於android服務這一塊。
1.瀏覽一下Android的system service
在命令行啓動shell
adb shell
執行下面指令
#service list
Found 47 services:
0 phone: [com.Android.internal.telephony.ITelephony]
1 iphonesubinfo: [com.Android.internal.telephony.IPhoneSubInfo]
2 simphonebook: [com.Android.internal.telephony.IIccPhoneBook]
3 isms: [com.Android.internal.telephony.ISms]
4 appwidget: [com.Android.internal.appwidget.IAppWidgetService]
42 SurfaceFlinger: [Android.ui.ISurfaceComposer]
43 media.audio_policy: [Android.media.IAudioPolicyService]
46 media.audio_flinger: [Android.media.IAudioFlinger]
從結果看來Android後臺有很多的system service,他們是分散在不同進程中的線程實體。
2.SystemServer
SystemServer是Android系統的一個核心進程,它是由zygote進程創建的,因此在android的啓動過程中位於zygote之後。android的所有服務循環都是建立在 SystemServer之上的。在SystemServer中,將可以看到它建立了android中的大部分服務,並通過ServerManager的add_service方法把這些服務加入到了ServiceManager的svclist中。從而完成ServcieManager對服務的管理。
3.Service Manager
Service manager是管理以上services的一個進程,可以在adb shell中運行ps看看進程列表就知道了。
源代碼位於:
frameworks/base/cmds/servicemanager
執行方式:
他是用c和c++語言編寫的natvie可以執行文件。在Android中稱之爲EXECUTABLE,這個名稱很重要因爲Android.mk文件中用這個名字來確定他是可以執行的二進制文件。
4.Service Manager的啓動過程和方法
開始有點複雜了,也該開始進入真正的Linux了。衆所周知Linux的啓動和文件系統的加載需要一個ramdisk,ramdisk負責讓Linux kernel加載第一個進程init進程。那麼這一切是怎麼發生的呢?
在Android的ramdisk中就有這樣一個可執行文件init,我們可以去看一下
system/core/init/init.c
int main(int argc, char **argv)
{
。。。。。。
parse_config_file("/init.rc");
。。。。。。
這個文件會編譯出一個init的二進制可執行文件,並且去讀init.rc文件。我們稱init.rc文件爲Android啓動配置腳本。
現在我們打開init.rc文件,(如果您不知道init.rc,請參考google吧,瞭解下它的語法)
## Daemon processes to be run by init.
##
service servicemanager /system/bin/servicemanager
user system
critical
onrestart restart zygote
onrestart restart media
從這裏可以看出servicemanager 是init通過init.rc加載的第一個進程,接下來啓動了zygote和media。
繼續閱讀init.rc
servicemanager進程運行起來以後,我們就可以應用binder來應用servicemanager提供的服務函數去創建
system-server和mediaserver了,下面是init.rc中的代碼
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
#system-server的創建是通過app_process這個二進制程序去加載的
socket zygote stream 666
onrestart write /sys/Android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart media
service media /system/bin/mediaserver #mediaserver的啓動代碼比較簡單,看看就知道了不用參數就創建了
user media
group system audio camera graphics inet net_bt net_bt_admin
5.回過頭再看系統的進程列表
# ps
USER PID PPID VSIZE RSS WCHAN PC NAME
root 1 0 296 204 c009a694 0000c93c S /init
root 2 0 0 0 c004dea0 00000000 S kthreadd
root 25 1 728 316 c003d444 afe0d6ac S /system/bin/sh
system 26 1 796 256 c019a810 afe0ca7c S /system/bin/servicemanager
root 30 1 82860 26580 c009a694 afe0cba4 S zygote
media 31 1 20944 3184 ffffffff afe0ca7c S /system/bin/mediaserver
root 32 1 784 280 c0209468 afe0c7dc S /system/bin/installd
keystore 33 1 1616 396 c01a65a4 afe0d40c S /system/bin/keystore
root 34 1 728 272 c003d444 afe0d6ac S /system/bin/sh
root 35 1 824 332 c00b7dd0 afe0d7fc S /system/bin/qemud
root 37 1 1308 152 ffffffff 0000eca4 S /sbin/adbd
root 44 34 780 304 c0209468 afe0c7dc S /system/bin/qemu-props
system 52 30 158356 37804 ffffffff afe0ca7c S system_server
app_1 92 30 108640 20580 ffffffff afe0da04 S com.Android.inputmethod.pinyin
radio 93 30 122852 23340 ffffffff afe0da04 S com.Android.phone
app_1 98 30 143244 34888 ffffffff afe0da04 S Android.process.acore
我們注意觀察進程列表的PID和PPID,我們要通過實際的列表去理清他們的親緣關係。
servicemanager是init的子進程
mediaserver是init的子進程
zygote是init的子進程,管理所有虛擬機實例
system_server和所有的java應用程序是zygote的子進程。system_server負責管理系統服務。
SystemServer進程
SystemServer進程在Android的運行環境中扮演了"神經中樞"的作用,APK應用中能夠直接交互的大部分系統服務都在該進程中運 行,常見的比如WindowManagerServer(Wms)、ActivityManagerSystemService(AmS)、 PackageManagerServer(PmS)等,這些系統服務都是以一個線程的方式存在於SystemServer進程中。下面就來介紹到底都有 哪些服務線程,及其啓動的順序。
SystemServer的main()函數首先調用的是init1()函數,這是一個native函數,內部會進行一些與Dalvik虛擬機相關 的初始化工作。該函數執行完畢後,其內部會調用Java端的init2()函數,這就是爲什麼Java源碼中沒有引用init2()的地方,主要的系統服 務都是在init2()函數中完成的。
該函數首先創建了一個ServerThread對象,該對象是一個線程,然後直接運行該線程,如以下代碼所示:
於是,從ServerThread的run()方法內部開始真正啓動各種服務線程。
基本上每個服務都有對應的Java類,從編碼規範的角度來看,啓動這些服務的模式可歸類爲三種,如圖9-3所示。
圖9-3 不同服務的啓動方式 |
模式一是指直接使用構造函數構造一個服務,由於大多數服務都對應一個線程,因此,在構造函數內部就會創建一個線程並自動運行。
模式二是指服務類會提供一個getInstance()方法,通過該方法獲取該服務對象,這樣的好處是保證系統中僅包含一個該服務對象。
模式三是指從服務類的main()函數中開始執行。
無論以上何種模式,當創建了服務對象後,有時可能還需要調用該服務類的init()或者systemReady()函數以完成該對象的啓動,當然這 些都是服務類內部自定義的。爲了區分以上啓動的不同,以下采用一種新的方式描述該啓動過程。比如當一個服務對象是通過模式一創建,並調用init()完成 該服務的啓動,我們就用模式1.2表示;如果構造函數返回後就已經啓動,而無須任何其他調用,即什麼都不做(nothing),我們就用模式1.1表示。
表9-2列出了SystemServer中所啓動的所有服務,以及這些服務的啓動模式。
表9-2 SystemServer中啓動服務列表
服務類名稱 |
作用描述 |
啓動模式 |
EntropyService |
提供僞隨機數 |
1.0 |
PowerManagerService |
電源管理服務 |
1.2/3 |
ActivityManagerService |
最核心的服務之一,管理 Activity |
自定義 |
TelephonyRegistry |
通過該服務註冊電話模塊的事件響應,比如重啓、關閉、啓動等 |
1.0 |
PackageManagerService |
程序包管理服務 |
3.3 |
AccountManagerService |
賬戶管理服務,是指聯繫人賬戶,而不是 Linux 系統的賬戶 |
1.0 |
ContentService |
ContentProvider 服務,提供跨進程數據交換 |
3.0 |
BatteryService |
電池管理服務 |
1.0 |
LightsService |
自然光強度感應傳感器服務 |
1.0 |
VibratorService |
震動器服務 |
1.0 |
AlarmManagerService |
定時器管理服務,提供定時提醒服務 |
1.0 |
WindowManagerService |
Framework 最核心的服務之一,負責窗口管理 |
3.3 |
BluetoothService |
藍牙服務 |
1.0 + |
DevicePolicyManagerService |
提供一些系統級別的設置及屬性 |
1.3 |
StatusBarManagerService |
狀態欄管理服務 |
1.3 |
ClipboardService |
系統剪切板服務 |
1.0 |
InputMethodManagerService |
輸入法管理服務 |
1.0 |
NetStatService |
網絡狀態服務 |
1.0 |
NetworkManagementService |
網絡管理服務 |
NMS.create() |
ConnectivityService |
網絡連接管理服務 |
2.3 |
ThrottleService |
暫不清楚其作用 |
1.3 |
(續表)
服務類名稱 |
作用描述 |
啓動模式 |
AccessibilityManagerService |
輔助管理程序截獲所有的用戶輸入,並根據這 些輸入給用戶一些額外的反饋,起到輔助的效果 |
1.0 |
MountService |
掛載服務,可通過該服務調用 Linux 層面的 mount 程序 |
1.0 |
NotificationManagerService |
通知欄管理服務, Android 中的通知欄和狀 態欄在一起,只是界面上前者在左邊,後者在右邊 |
1.3 |
DeviceStorageMonitorService |
磁盤空間狀態檢測服務 |
1.0 |
LocationManagerService |
地理位置服務 |
1.3 |
SearchManagerService |
搜索管理服務 |
1.0 |
DropBoxManagerService |
通過該服務訪問 Linux 層面的 Dropbox 程序 |
1.0 |
WallpaperManagerService |
牆紙管理服務,牆紙不等同於桌面背景, 在 View 系統內部,牆紙可以作爲任何窗口的背景 |
1.3 |
AudioService |
音頻管理服務 |
1.0 |
BackupManagerService |
系統備份服務 |
1.0 |
AppWidgetService |
Widget 服務 |
1.3 |
RecognitionManagerService |
身份識別服務 |
1.3 |
DiskStatsService |
磁盤統計服務 |
1.0 |
AmS的啓動模式如下:
調用main()函數,返回一個Context對象,而不是AmS服務本身。
調用AmS.setSystemProcess()。
調用AmS.installProviders()。
調用systemReady(),當AmS執行完systemReady()後,會相繼啓動相關聯服務的systemReady()函數,完成整體初始化。
關於具體某個服務的內部啓動過程,請參照源碼,這些過程一般都比較簡單。