android系統服務啓動分析-binder

轉自:http://blog.csdn.net/rickleaf/archive/2011/04/28/6369720.aspx

1.System Services

首先我要聲明一下,我講的System Services並非Android 開發應用程序時,所涉及的Service(後臺應用服務程序)的概念。

我要講的System Services是Android操作系統Java應用程序下層的,伴隨操作系統啓動而運行的系統後臺服務程序。

它是Android系統運行的基石,它配合binder(Android多進程通訊方法)、dalvik虛擬機和Android應用程序構成了一個多進程

交互通訊,交互服務的Android系統。

2.瀏覽一下Android系統的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後臺有很多的service,他們是分散在不同進程中的線程實體(有點繞嘴,但是我認爲這樣說比較確切)。

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

4.system server進程

繼續閱讀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的子進程

休息一下我們看看他們的應用程序代碼方式

Java script caller (executable)
frameworks/base/cmds/app_process/
app_main.cpp

app_process是android系統下面基於命令行的java的應用程序的調用工具

system_server executable(c/c++寫的程序)


frameworks/base/cmds/system_server/

system_main.cpp
library/system_init.cpp

SystemServer (java程序)
frameworks/base/services/java/com/android/server/
SystemServer.java


Zygote (java程序)
frameworks/base/core/java/com/android/internal/os/
ZygoteInit.java

6.分析具體的調用過程(很痛苦)

app_main 調用 zygoteInit

p { margin-bottom: 0.21cm; }

/ Next arg is startup classname or "--zygote"

if ( i < argc ) {

arg = argv [ i ++];

if ( 0 == strcmp ( "--zygote" , arg )) {

bool startSystemServer = ( i < argc ) ?

strcmp ( argv [ i ], "--start-system-server" ) == 0 : false ;

setArgv0 ( argv0 , "zygote" );

set_process_name ( "zygote" );

runtime. start ( "com.android.internal.os.ZygoteInit" ,

startSystemServer );

} else {

set_process_name ( argv0 );


runtime. mClassName = arg ;


// Remainder of args get passed to startup class main ()

runtime. mArgC = argc - i ;

runtime. mArgV = argv + i ;


LOGV ( "App process is starting with pid=%d, class=%s. /n " ,

getpid (), runtime. getClassName ());

runtime. start ();

}

}


Zygote 分裂出 system_server



p { margin-bottom: 0.21cm; }

public static void main ( String argv []) {

try {

// Start profiling the zygote initialization.

if ( argv [ 1 ] . equals ( "true" )) {

startSystemServer ();

}

Log. i ( TAG, "Accepting command socket connections" );


if ( ZYGOTE_FORK_MODE ) {

runForkMode ();

} else {

runSelectLoopMode ();

}

}


frameworks/base/core/java/com/android/internal/os/
ZygoteInit.java

p { margin-bottom: 0.21cm; }

private static boolean startSystemServer()

throws MethodAndArgsCaller, RuntimeException {

/* Hardcoded command line to start the system server */

try {

/* Request to fork the system server process */

pid = Zygote. forkSystemServer (

parsedArgs. uid , parsedArgs. gid ,

parsedArgs. gids , debugFlags, null );

} catch ( IllegalArgumentException ex) {

throw new RuntimeException (ex);

}

/* For child process */

if (pid == 0 ) {

handleSystemServerProcess(parsedArgs);

}

return true ;

}


1.如果大家還能看到這裏請複習一下 Linux的兩個系統調用 fork和exec


frameworks/base/services/java/com/android/server/SystemService.java

p { margin-bottom: 0.21cm; }

public static void main ( String [] args ) {

if ( SamplingProfilerIntegration. isEnabled ()) {

SamplingProfilerIntegration. start ();

timer = new Timer ();

timer . schedule ( new TimerTask () {

@ Override

public void run () {

SamplingProfilerIntegration. writeSnapshot ( "system_server" );

}

} , SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL );

}

VMRuntime. getRuntime () . setTargetHeapUtilization ( 0 .8f );

System . loadLibrary ( "android_servers" );

init1 ( args );------------------>

}


public static final void init2 () {

Log. i ( TAG, "Entered the Android system server!" );

Thread thr = new ServerThread ();

thr. setName ( "android.server.ServerThread" );-------------->

thr.start();

}



紅色的部分最後會執行我們上面列出的jni代碼

frameworks/base/cmds/system_server/
library/system_init.cpp


Init2 這裏啓動了java的system service


p { margin-bottom: 0.21cm; }

class ServerThread extends Thread {

@ Override

public void run () {


Log. i ( TAG, "System Content Providers" );

ActivityManagerService. installSystemProviders ();


Log. i ( TAG, "Battery Service" );

battery = new BatteryService ( context );

ServiceManager. addService ( "battery" , battery );


Log. i ( TAG, "Hardware Service" );

hardware = new HardwareService ( context );

ServiceManager. addService ( "hardware" , hardware );


Log. i ( TAG, "Alarm Manager" );

AlarmManagerService alarm = new AlarmManagerService ( context );

ServiceManager. addService ( Context . ALARM_SERVICE , alarm );


}

}

 

原創文章歡迎轉載,轉載請註明住處rickleaf

7. 整理Android系統啓動流程

至此System Service的服務環境啓動起來了


8. 最後引用霍金的一句話:“懂與不懂都是收穫”

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