ikautak.log

C/C++, Python, CUDA, Android, Linux kernel, Network, etc.

startActivityの深層 後編

前回のつづき

android.os.ProcessクラスのzygoteSendArgsAndGetPid()でsocketにいろいろwriteすると、pidがreadできる。
socketのreadをしているプロセスがいて、それがforkしてpidを返している。

アプリのプロセスの親プロセスはzygote

emulatorを起動してadb shellでpsコマンドを実行すると、各プロセスの親プロセスがわかる。

PIDがプロセスID、PPIDが親プロセスのID。

# ps
USER     PID   PPID  VSIZE  RSS     WCHAN    PC         NAME
root      1     0     268    180   c009b74c 0000875c S /init
root      2     0     0      0     c004e72c 00000000 S kthreadd
root      3     2     0      0     c003fdc8 00000000 S ksoftirqd/0
root      4     2     0      0     c004b2c4 00000000 S events/0
root      5     2     0      0     c004b2c4 00000000 S khelper

...

root      32    1     63964  21732 c009b74c afd0b844 S zygote
media     33    1     17212  1368  ffffffff afd0b6fc S /system/bin/mediaserver
root      34    1     812    240   c02181f4 afd0b45c S /system/bin/installd
keystore  35    1     1796   280   c01b52b4 afd0c0cc S /system/bin/keystore
root      37    1     824    276   c00b8fec afd0c51c S /system/bin/qemud
shell     39    1     732    204   c0158eb0 afd0b45c S /system/bin/sh
root      40    1     3376   180   ffffffff 00008294 S /sbin/adbd
system    60    32    125208 31256 ffffffff afd0b6fc S system_server
app_12    112   32    76032  19472 ffffffff afd0c51c S jp.co.omronsoft.openwnn
radio     118   32    88352  20500 ffffffff afd0c51c S com.android.phone
system    121   32    76268  20780 ffffffff afd0c51c S com.android.systemui
app_1     123   32    79236  23488 ffffffff afd0c51c S com.android.launcher
app_5     180   32    76352  20236 ffffffff afd0c51c S android.process.acore
root      186   40    732    204   c003da38 afd0c3ac S /system/bin/sh
root      187   186   688    280   c009b74c afd0b844 S logcat
app_8     201   32    74148  18368 ffffffff afd0c51c S com.android.deskclock
app_3     216   32    85184  18344 ffffffff afd0c51c S com.android.mms
app_9     220   32    75120  18892 ffffffff afd0c51c S android.process.media
app_13    247   32    75608  19472 ffffffff afd0c51c S com.android.email
app_11    262   32    72816  16836 ffffffff afd0c51c S com.android.protips
app_20    274   32    73256  17272 ffffffff afd0c51c S com.android.music
app_26    282   32    73852  18080 ffffffff afd0c51c S com.android.quicksearchbox
root      292   40    732    328   c003da38 afd0c3ac S /system/bin/sh
root      294   292   888    328   00000000 afd0b45c R ps

com.android.xxxなどのアプリは全てPID 32のzygoteがforkしている。

zygoteプロセスはinit.rcから起動される。ソースは
/frameworks/base/cmds/app_process/app_main.cpp

app_main.cppのmain関数でcom.android.internal.os.ZygoteInitのstatic mainを実行する。
↓
ZygoteInit
  main()
    registerZygoteSocket()  // サーバー側socketを初期化

    preloadClasses()        // frameworkのクラスを予め読む
                            // Class.forName()を呼んで、戻り値は見ない

    preloadResources()      // Resourceを読む

    runSelectLoopMode()     // select()でsocketの書き込み待ち
                            // 書き込みがあると、ZygoteConnection.runOnce()へ

ZygoteConnection
  runOnce()                 // 引数をチェックしたり、uidとか決める
  ↓
Zygote
  forkAndSpecialize()       // libcore/dalvik/src/main/java/dalvik/system/Zygote.java
                            // native method呼ぶだけ
  ↓
/dalvik/vm/native/dalvik_system_Zygote.c
  forkAndSpecializeCommon()  // ココでfork()してる!

preloadClasses()はLogcatに

INFO/Zygote(32): ...preloaded 1830 classes in 7118ms.

みたいなログを出すやつ。 予め全部クラスをロードしたプロセスを作っておき、Processクラスの要求でforkしている。
zygoteはアプリのための初期化済みプロセスで、forkするサーバを兼ねているようだ。