Android系統(tǒng)啟動(dòng)過程詳解

前言


一直想研究Android完整的啟動(dòng)過程,網(wǎng)上看了不少資料,也看了書上的一些說明,對(duì)這些觀點(diǎn)有些懷疑,于是自己分析了系統(tǒng)啟動(dòng)的完整過程。從內(nèi)核啟動(dòng)第一個(gè)用戶程序init開始說起,直到Home應(yīng)用的啟動(dòng),每一步都有源代碼展示。希望能解除讀者對(duì)Android系統(tǒng)啟動(dòng)過程中的困惑,若有什么疑問,歡迎留言交流。本研究基于CM10.1源碼,讀者若能對(duì)照源代碼查看效果會(huì)更好。

1) init啟動(dòng)servicemanager和 zygote兩個(gè)service


Android底層是Linux內(nèi)核,和linux類似,內(nèi)核初始化后啟動(dòng)的第一個(gè)用戶進(jìn)程是init,它會(huì)解析init.rc腳本,啟動(dòng)init.rc里聲明的service,并執(zhí)行一些action。在init.rc里有啟動(dòng)Andriod空間的一些關(guān)鍵服務(wù),代碼如下:

#…
service servicemanager /system/bin/servicemanager
    class core
    user system
    group system
    critical
    onrestart restart zygote
    onrestart restart media
    onrestart restart surfaceflinger
    onrestart restart drm
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
    class main
    socket zygote stream 660 root system
    onrestart write /sys/android_power/request_state wake
    onrestart write /sys/power/state on
    onrestart restart media
    onrestart restart netd
#…

servicemanager負(fù)責(zé)管理所有的binder service, 這些binder service有native的,也有java的。native的binder service有surfaceflinger,drm,media等,java的binder service就有我們平常熟悉的很多管理服務(wù)了,ActivityManagerService,WindowManagerService,BatteryService,PowerManagerService,InputManagerService等等。service manager并不負(fù)責(zé)這些binder service的創(chuàng)建,native的binder service大多由init啟動(dòng)init.rc里的service時(shí)創(chuàng)建并啟動(dòng),java層的binder service大多由zygote創(chuàng)建并啟動(dòng)的,接下來會(huì)詳細(xì)這些service是如何被啟動(dòng)的。

2) zygote service啟動(dòng)java層的ZygoteInit


zygote服務(wù)是java層所有程序進(jìn)程的父進(jìn)程,它是Android空間程序的孵化器,Android空間所有程序都是由zygote進(jìn)程啟動(dòng)的。zygote service對(duì)應(yīng)/system/bin/app_process程序,源代碼位于frameworks/base/cmds/app_process/app_main.cpp,啟動(dòng)時(shí)的main函數(shù)代碼如下:

int main(int argc, const char* const argv[])
{
//...
/*runtime就是dalvik虛擬機(jī)實(shí)例,啟動(dòng)Java層應(yīng)用時(shí),
 *會(huì)fork 一個(gè)子進(jìn)程,復(fù)制虛擬機(jī),許多書上將runtime看作一個(gè)進(jìn)程,
 *然后再啟動(dòng)zygote進(jìn)程,個(gè)人覺得這是錯(cuò)誤的 
 */\t\t 
AppRuntime runtime;
//... 
while (i < argc) {
    const char* arg = argv[i++];
    if (!parentDir) {
        parentDir = arg;
  /*init.rc啟動(dòng)app_main會(huì)設(shè)置參數(shù)--zygote*/ 
    } else if (strcmp(arg, "--zygote") == 0) {
        zygote = true;
        niceName = "zygote"; //進(jìn)程的名字
  /*init.rc啟動(dòng)app_main會(huì)設(shè)置參數(shù)--start-system-server,
   *表示需啟動(dòng)systemserver
   */
    } else if (strcmp(arg, "--start-system-server") == 0) {
        startSystemServer = true;
 /*啟動(dòng)應(yīng)用時(shí)會(huì)使用--application參數(shù)*/             
    } else if (strcmp(arg, "--application") == 0) {
        application = true;
/*--nice-name=參數(shù)表示要設(shè)置的進(jìn)程名字*/            
    } else if (strncmp(arg, "--nice-name=", 12) == 0) {
        niceName = arg + 12;
    } else {
        className = arg;
        break;
    }
}    
/*設(shè)置進(jìn)程名*/
if (niceName && *niceName) {
    setArgv0(argv0, niceName);
    set_process_name(niceName);
}
/*設(shè)置虛擬機(jī)運(yùn)行環(huán)境的父目錄*/
runtime.mParentDir = parentDir;
if (zygote) {
/*虛擬機(jī)里啟動(dòng)com.android.internal.os.ZygoteInit,
 *并傳遞參數(shù)start-system-server
 */
    runtime.start("com.android.internal.os.ZygoteInit",
            startSystemServer ? "start-system-server" : "");
} else if (className) {        
    /*若不是zygote,則啟動(dòng)的第一個(gè)類是com.android.internal.os.RuntimeInit,
     *RumtimeInit初始化后會(huì)啟動(dòng)mClassName
     */
    runtime.mClassName = className;
    runtime.mArgC = argc - i;
    runtime.mArgV = argv + i;
    runtime.start("com.android.internal.os.RuntimeInit",
            application ? "application" : "tool");
} else {
    fprintf(stderr, "Error: no class name or --zygote supplied.\\n");
    app_usage();
    LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
    return 10;
}
//...
}

通過上述代碼可知道zygote service將運(yùn)行dalvik虛擬機(jī),并在虛擬機(jī)里執(zhí)行com.android.internal.os.ZygoteInit,還給它傳遞了參數(shù)start-system-server

3) ZygoteInit啟動(dòng)SystemServer


ZygoteInit啟動(dòng)時(shí)的相關(guān)源代碼:

public static void main(String argv[]) {
{
try {   
   //...
   //在某個(gè)描述符上監(jiān)聽連接請(qǐng)求,
   //其它Android空間的程序的啟動(dòng)都是通過連接zygote才孵化出來的
   registerZygoteSocket();
   //... 
   if (argv[1].equals("start-system-server")) {
        //啟動(dòng)SystemServer
        startSystemServer();
    } else if (!argv[1].equals("")) {
        throw new RuntimeException(argv[0] + USAGE_STRING);
    }
   //...
   /*ZYGOTE_FORK_MODE默認(rèn)為false,如果為true的話,每收到一個(gè)連接請(qǐng)求,
    *就會(huì)建立一個(gè)新進(jìn)程,然后再運(yùn)行連接請(qǐng)求所要求執(zhí)行的命令,此時(shí)會(huì)建立另一個(gè)新進(jìn)程
    */
    if (ZYGOTE_FORK_MODE) {
        runForkMode();
    } else {
       //使用Select poll的方式來建立新進(jìn)程,收到連接請(qǐng)求后,也會(huì)建立進(jìn)程啟動(dòng)某個(gè)程序
        runSelectLoopMode();
    }

    closeServerSocket();
} catch (MethodAndArgsCaller caller) {
    caller.run();
} catch (RuntimeException ex) {
    Log.e(TAG, "Zygote died with exception", ex);
    closeServerSocket();
    throw ex;
}
}

從上述代碼可知道會(huì)調(diào)用startSystemServer以啟動(dòng)SystemServer,相關(guān)源代碼如下:

private static boolean startSystemServer()
{
/* Hardcoded command line to start the system server */
//啟動(dòng)SystemServer使用的參數(shù)
String args[] = {
    "--setuid=1000",
    "--setgid=1000",
    "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,3001,3002,3003,3004,3006,3007,3009",
    "--capabilities=130104352,130104352",
    "--runtime-init",
    "--nice-name=system_server",
    //注意:就是在這里設(shè)置要啟動(dòng)的SystemServer包名及類名,故此后續(xù)才能啟動(dòng)SystemServer
    "com.android.server.SystemServer",
};
ZygoteConnection.Arguments parsedArgs = null;
int pid;
try {
    /*將args參數(shù)傳給ZygoteConnection進(jìn)行轉(zhuǎn)化,--形式的參數(shù)將全部被接收
     * 但是要啟動(dòng)的類的類名com.android.server.SystemServer會(huì)放在
     *ZygoteConnection.Arguments的remainingArgs里,后來調(diào)用handleSystemServerProcess時(shí)會(huì)用到
     */
    parsedArgs = new ZygoteConnection.Arguments(args); 
    /*添加額外運(yùn)行參數(shù)*/
    ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
    ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs); 
    /*開啟新進(jìn)程*/
    pid = Zygote.forkSystemServer(
            parsedArgs.uid, parsedArgs.gid,
            parsedArgs.gids,
            parsedArgs.debugFlags,
            null,
            parsedArgs.permittedCapabilities,
            parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
    throw new RuntimeException(ex);
} 
/* For child process */
if (pid == 0) {
\t  /*調(diào)用handleSystemServerProcess會(huì)執(zhí)行ZygoteConnection.Arguments的remainingArgs參數(shù)
\t   *所指定的類,即com.android.server.SystemServer\t   
\t   */
    handleSystemServerProcess(parsedArgs);
}
}

ZygoteInit的startSystemServer會(huì)調(diào)用forkSystemServer,然后:

ZygoteInit.forkSystemServer -> Zygote.nativeForkSystemServer-> dalvik_system_Zygote.cpp 里的Dalvik_dalvik_system_Zygote_forkSystemServer-> forkAndSpecializeCommon->fork建立新進(jìn)程

ZygoteInit的startSystemServer會(huì)調(diào)用handleSystemServerProcess來真正啟動(dòng)systemserver,相關(guān)源代碼如下:

private static void handleSystemServerProcess(
            ZygoteConnection.Arguments parsedArgs)
            throws ZygoteInit.MethodAndArgsCaller {
//... 
if (parsedArgs.niceName != null) {
    Process.setArgV0(parsedArgs.niceName);
}
//啟動(dòng)systemserver時(shí)invokeWith為null
if (parsedArgs.invokeWith != null) {
    WrapperInit.execApplication(parsedArgs.invokeWith,
            parsedArgs.niceName, parsedArgs.targetSdkVersion,
            null, parsedArgs.remainingArgs);
} else {
    /*
     * 啟動(dòng)systemserver時(shí),parsedArgs.remainingArgs為com.android.server.SystemServer.
     */
    RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs);
}
}

然后的流程是

RuntimeInit.zygoteInit-> applicationInit,applicationInit的代碼如下所示:

private static void applicationInit(int targetSdkVersion, String[] argv)
{
//...
final Arguments args;
try {
    //參數(shù)轉(zhuǎn)換,系統(tǒng)啟動(dòng)時(shí),argv里有一個(gè)參數(shù)是com.android.server.SystemServer
    args = new Arguments(argv);
} catch (IllegalArgumentException ex) {
    Slog.e(TAG, ex.getMessage());
    // let the process exit
    return;
}
//...
//終于在此啟動(dòng)了SystemServer
invokeStaticMain(args.startClass, args.startArgs)
}

4) SystemServer 啟動(dòng)過程


執(zhí)行com.android.server.SystemServer時(shí),main函數(shù)里會(huì)調(diào)用init1函數(shù),init1函數(shù)是一個(gè)本地函數(shù),init1的實(shí)現(xiàn)放在frameworks/base/services/jni/com_android_server_SystemServer.cpp里,對(duì)應(yīng)的jni函數(shù)是android_server_SystemServer_init1,在該函數(shù)里會(huì)調(diào)用system_init,而system_init的實(shí)現(xiàn)是在frameworks/base/cmds/system_server/library/system_init.cpp,該函數(shù)的實(shí)現(xiàn)代碼如下所示:

extern "C" status_t system_init()
{
//... 
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm = defaultServiceManager();
ALOGI("ServiceManager: %p\\n", sm.get());
sp<GrimReaper> grim = new GrimReaper();
sm->asBinder()->linkToDeath(grim, grim.get(), 0);
char propBuf[PROPERTY_VALUE_MAX];
property_get("system_init.startsurfaceflinger", propBuf, "1");
if (strcmp(propBuf, "1") == 0) {
    // Start the SurfaceFlinger
    SurfaceFlinger::instantiate();
}
property_get("system_init.startsensorservice", propBuf, "1");
if (strcmp(propBuf, "1") == 0) {
    // Start the sensor service
    SensorService::instantiate();
}
// And now start the Android runtime.  We have to do this bit
// of nastiness because the Android runtime initialization requires
// some of the core system services to already be started.
// All other servers should just start the Android runtime at
// the beginning of their processes's main(), before calling
// the init function.
ALOGI("System server: starting Android runtime.\\n");
AndroidRuntime* runtime = AndroidRuntime::getRuntime();
ALOGI("System server: starting Android services.\\n");
JNIEnv* env = runtime->getJNIEnv();
if (env == NULL) {
    return UNKNOWN_ERROR;
}
jclass clazz = env->FindClass("com/android/server/SystemServer");
if (clazz == NULL) {
    return UNKNOWN_ERROR;
}
//反過來調(diào)用Java里SystemServer的init2函數(shù)
jmethodID methodId = env->GetStaticMethodID(clazz, "init2", "()V");
if (methodId == NULL) {
    return UNKNOWN_ERROR;
}
env->CallStaticVoidMethod(clazz, methodId);
ALOGI("System server: entering thread pool.\\n");
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
ALOGI("System server: exiting thread pool.\\n");
}

5) 啟動(dòng)Java層的各種binder service


調(diào)用SystemServer的init2函數(shù)后,會(huì)開啟新線程android.server.ServerThread,在新線程里會(huì)啟動(dòng)各種Java層的binder service,并在service manager里注冊(cè),這些Service大多開啟了新線程運(yùn)行,故此都是systemserver的子線程,添加的Service列表如下所示:

ServiceManager.addService("entropy", new EntropyMixer());
ServiceManager.addService(Context.POWER_SERVICE, power);
ServiceManager.addService(Context.DISPLAY_SERVICE, display, true);
ServiceManager.addService("telephony.registry", telephonyRegistry);
ServiceManager.addService(Context.SCHEDULING_POLICY_SERVICE,
ServiceManager.addService(Context.USER_SERVICE,UserManagerService.getInstance());
ServiceManager.addService(Context.ACCOUNT_SERVICE, accountManager);
ServiceManager.addService("battery", battery);
ServiceManager.addService("vibrator", vibrator);
ServiceManager.addService(Context.ALARM_SERVICE, alarm);
ServiceManager.addService(Context.WINDOW_SERVICE, wm);
ServiceManager.addService(Context.INPUT_SERVICE, inputManager);
ServiceManager.addService(BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE, bluetooth);
ServiceManager.addService(Context.INPUT_METHOD_SERVICE, imm);
ServiceManager.addService(Context.ACCESSIBILITY_SERVICE,new AccessibilityManagerService(context));
ServiceManager.addService("mount", mountService);
ServiceManager.addService("lock_settings", lockSettings);
ServiceManager.addService(Context.DEVICE_POLICY_SERVICE, devicePolicy);
ServiceManager.addService(Context.STATUS_BAR_SERVICE, statusBar);
ServiceManager.addService(Context.CLIPBOARD_SERVICE,new ClipboardService(context));
ServiceManager.addService(Context.NETWORKMANAGEMENT_SERVICE, networkManagement);
ServiceManager.addService(Context.TEXT_SERVICES_MANAGER_SERVICE, tsms);
ServiceManager.addService(Context.NETWORK_STATS_SERVICE, networkStats);
ServiceManager.addService(Context.NETWORK_POLICY_SERVICE, networkPolicy);
ServiceManager.addService(Context.WIFI_P2P_SERVICE, wifiP2p);
ServiceManager.addService(Context.WIFI_SERVICE, wifi);
ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity);
ServiceManager.addService(Context.NSD_SERVICE, serviceDiscovery);
ServiceManager.addService(Context.THROTTLE_SERVICE, throttle);
ServiceManager.addService("fm_receiver",new FmReceiverService(context));
ServiceManager.addService("fm_transmitter",new FmTransmitterService(context));
ServiceManager.addService(Context.UPDATE_LOCK_SERVICE,new UpdateLockService(context));
ServiceManager.addService(Context.PROFILE_SERVICE, profile);
ServiceManager.addService(Context.NOTIFICATION_SERVICE, notification);
ServiceManager.addService(DeviceStorageMonitorService.SERVICE,
ServiceManager.addService(Context.LOCATION_SERVICE, location);
ServiceManager.addService(Context.COUNTRY_DETECTOR, countryDetector);
ServiceManager.addService(Context.SEARCH_SERVICE,new SearchManagerService(context));
ServiceManager.addService(Context.DROPBOX_SERVICE,new DropBoxManagerService(context, new File("/data/system/dropbox")));
ServiceManager.addService(Context.WALLPAPER_SERVICE, wallpaper);
ServiceManager.addService(Context.AUDIO_SERVICE, new AudioService(context));
ServiceManager.addService(Context.USB_SERVICE, usb);
ServiceManager.addService(Context.SERIAL_SERVICE, serial);
ServiceManager.addService(Context.BACKUP_SERVICE,new BackupManagerService(context));
ServiceManager.addService(Context.APPWIDGET_SERVICE, appWidget);
ServiceManager.addService("diskstats", new DiskStatsService(context));
ServiceManager.addService("samplingprofiler", new SamplingProfilerService(context));
ServiceManager.addService("commontime_management", commonTimeMgmtService);
ServiceManager.addService(DreamService.DREAM_SERVICE, dreamy);
ServiceManager.addService("assetredirection", new AssetRedirectionManagerService(context));
ServiceManager.addService("pieservice", pieService);

上述并沒有看到將ActivityManagerService添加到servicemanager管理,它的添加過程比較特別。在線程android.server.ServerThread里會(huì)調(diào)用ActivityManagerService.setSystemProcess();setSystemProcess函數(shù)的代碼如下所示:

public static void setSystemProcess() {
//…
ActivityManagerService m = mSelf;            
ServiceManager.addService("activity", m, true);
ServiceManager.addService("meminfo", new MemBinder(m));
ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
ServiceManager.addService("dbinfo", new DbBinder(m));
if (MONITOR_CPU_USAGE) {
    ServiceManager.addService("cpuinfo", new CpuBinder(m));
}
ServiceManager.addService("permission", new PermissionController(m));
ApplicationInfo info =
    mSelf.mContext.getPackageManager().getApplicationInfo(
                "android", STOCK_PM_FLAGS);
mSystemThread.installSystemApplicationInfo(info);
//…
}

可以看到ActivityManagerService采用了單例模式,并調(diào)用ServiceManager.addService("activity", m, true);將ActivityManagerService交給servicemanager管理,在ActivityManagerService里還添加了別的binder service,像MemBinder,GraphicsBinder,DbBinder。

最后會(huì)調(diào)用Looper.loop();進(jìn)入loop循環(huán),等待和別的程序通信。

  1. 啟動(dòng)系統(tǒng)界面

線程android.server.ServerThread里有如下代碼:

ActivityManagerService.self().systemReady(new Runnable() {
    public void run() {
        Slog.i(TAG, "Making services ready");

        if (!headless) startSystemUi(contextF);
        //...
     }
}

startSystemUi就是用于啟動(dòng)系統(tǒng)界面的,代碼如下:

static final void startSystemUi(Context context) {
        Intent intent = new Intent();
        intent.setComponent(new ComponentName("com.android.systemui",
                    "com.android.systemui.SystemUIService"));
        //Slog.d(TAG, "Starting service: " + intent);
        context.startServiceAsUser(intent, UserHandle.OWNER);
}

這樣便啟動(dòng)了com.android.systemui應(yīng)用,該應(yīng)用將啟動(dòng)PowerUI和RingtonePlayer兩個(gè)線程。

  1. 啟動(dòng)Home 程序

線程android.server.ServerThread里有如下代碼:

//…
ActivityManagerService.self().systemReady(new Runnable() {
            public void run() {
                  //…
                }
    });
//…

ActivityManagerService.self().systemReady有如下代碼:

//…
mMainStack.resumeTopActivityLocked(null);
//…

ActivityStack. resumeTopActivityLocked()有如下代碼:

resumeTopActivityLocked(prev, null);

resumeTopActivityLocked的實(shí)現(xiàn)有如下代碼:

//…
if (next == null) {
    // There are no more activities!  Let's just start up the
    // Launcher...
    if (mMainStack) {
        ActivityOptions.abort(options); 
        return mService.startHomeActivityLocked(mCurrentUser);
    }
}
//…

mService類型是ActivityManagerService,ActivityManagerService. startHomeActivityLocked的實(shí)現(xiàn)有如下代碼:

boolean startHomeActivityLocked(int userId) {
//…
Intent intent = new Intent(
    mTopAction,
    mTopData != null ? Uri.parse(mTopData) : null);
intent.setComponent(mTopComponent);
//這里便添加了Intent.CATEGORY_HOME,
//所有的Home應(yīng)用都會(huì)都帶有該類型的Activity,只有這樣才會(huì)被認(rèn)為是Home應(yīng)用
if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
    intent.addCategory(Intent.CATEGORY_HOME);
}
ActivityInfo aInfo =
    resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
if (aInfo != null) {
    intent.setComponent(new ComponentName(
            aInfo.applicationInfo.packageName, aInfo.name));
    // Don't do this if the home app is currently being
    // instrumented.
    aInfo = new ActivityInfo(aInfo);
    aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
    ProcessRecord app = getProcessRecordLocked(aInfo.processName,
            aInfo.applicationInfo.uid);
    if (app == null || app.instrumentationClass == null) {
        intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
        mMainStack.startActivityLocked(null, intent, null, aInfo,
                null, null, 0, 0, 0, 0, null, false, null);
    }
}
}

這樣先找到使用Intent.CATEGORY_HOME聲明的Activity組件,然后再調(diào)用mMainStack.startActivityLocked啟動(dòng)該Activity。

system server啟動(dòng)Home程序總結(jié):

android.server.ServerThread->ActivityManagerService.self().systemReady->mMainStack.resumeTopActivityLocked->resumeTopActivityLocked-> mService.startHomeActivityLocked-> intent.addCategory(Intent.CATEGORY_HOME);mMainStack.startActivityLocked

總結(jié)

內(nèi)核初始化好后,運(yùn)行的第一個(gè)用戶程序是init,init將啟動(dòng)init.rc里聲明的多個(gè)service,跟Android空間相關(guān)的有servicemanager和zygote,servicemanager負(fù)責(zé)管理所有的binder service,zygote負(fù)責(zé)孵化所有Android空間的程序。zygote service對(duì)應(yīng)的程序是app_process,不過加了一些啟動(dòng)參數(shù),所以它會(huì)啟動(dòng)Java層的ZygoteInit,在ZygoteInit里會(huì)啟動(dòng)SystemServer,SystemServer分為兩個(gè)階段:本地的init1和Java層的init2,init2里會(huì)啟動(dòng)線程android.server.ServerThread。在android.server.ServerThread線程里會(huì)啟動(dòng)Java層的各種binder service,比如ActivityManagerService,PackageManagerService,WindowManagerService。然后調(diào)用ActivityManagerService的systemReady方法,在該方法里會(huì)啟動(dòng)系統(tǒng)界面以及Home程序。

轉(zhuǎn)載至:http://www.cloudchou.com/android/post-361.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容