Android系統(tǒng)啟動(dòng)流程源碼分析

用Source Insight來(lái)追蹤Android系統(tǒng)啟動(dòng)流程的源碼拾酝,并將我認(rèn)為重要的源碼進(jìn)行分析

1缘屹、當(dāng)系統(tǒng)引導(dǎo)程序啟動(dòng)Linux內(nèi)核透乾,內(nèi)核會(huì)記載各種數(shù)據(jù)結(jié)構(gòu)和驅(qū)動(dòng)程序,加載完畢之后熔恢,Android系統(tǒng)開始啟動(dòng)并加載第一個(gè)用戶級(jí)別的進(jìn)程:Init.c(system\core\init)

//Init.c中的main()方法
int main(int argc, char **argv)
{
    //解析執(zhí)行init.rc配置文件
    init_parse_config_file("/init.rc");
}

2脐湾、執(zhí)行配置文件init.rc(system\core\rootdir)中定義好的指令,進(jìn)行環(huán)境初始化叙淌;執(zhí)行了很多bin指令沥割,來(lái)啟動(dòng)系統(tǒng)服務(wù)

//啟動(dòng)孵化器進(jìn)程,執(zhí)行app_process(一個(gè)編譯好的可執(zhí)行文件)
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server 
  socket zygote stream 666
  onrestart write /sys/android_power/request_state wake 
  onrestart write /sys/power/state on 
  onrestart restart media onrestart restart netd

3凿菩、在app_process文件下找到app_main.cpp,查看main()方法

int main(int argc, const char* const argv[])
{
    //啟動(dòng)一個(gè)系統(tǒng)服務(wù):ZygoteInit
  runtime.start("com.android.internal.os.ZygoteInit",startSystemServer);
}

4帜讲、在ZygoteInit.java中衅谷,查看main()方法

public static void main(String argv[]) {
    //預(yù)加載Android系統(tǒng)所需要的類
    preloadClasses();
    if (argv[1].equals("true")) {
        //調(diào)用方法開啟系統(tǒng)服務(wù)
        startSystemServer();
     }
}

preloadClasses(),加載Android運(yùn)行時(shí)環(huán)境

/**
* The name of a resource file that contains classes to preload.
*/
//“preloaded-classes”這個(gè)文件里面是Android中所有需要加載的全包名
private static final String PRELOADED_CLASSES = "preloaded-classes";

private static void preloadClasses() {
    //用類加載器似将,根據(jù)文件名获黔,加載資源作為一個(gè)輸入流
    InputStream is = ZygoteInit.class.getClassLoader().getResourceAsStream(PRELOADED_CLASSES);
    BufferedReader br = new BufferedReader(new InputStreamReader(is), 256);
    String line;
    //一行一行的讀取全包名
    while ((line = br.readLine()) != null) {
    //根據(jù)全包名加載類
      Class.forName(line);
    }  

}

startSystemServer(),這個(gè)方法開啟系統(tǒng)服務(wù)

String args[] = {
     "--setuid=1000",
     "--setgid=1000",
     "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,
                  1009,1010,1018,3001,3002,3003",
     "--capabilities=130104352,130104352",
     "--runtime-init",
     "--nice-name=system_server",
     //開啟SystemServer服務(wù)
     "com.android.server.SystemServer",
};

5在验、啟動(dòng)SystemServer服務(wù)

//C庫(kù)中的init1()方法
native public static void init1(String[] args);

public static void main(String[] args) {
    //加載C庫(kù)
    System.loadLibrary("android_servers");
    //執(zhí)行C庫(kù)里的init1方法
    init1(args);
}

在om_android_server_SystemServer.cpp文件玷氏,找到init1()方法

static JNINativeMethod gMethods[] = {
    /* name, signature, funcPtr */
    //給init1方法映射一個(gè)指針,最后調(diào)用了system_init()方法腋舌,而system_init()沒(méi)有方法體
    { "init1", "([Ljava/lang/String;)V", (void*)   
    android_server_SystemServer_init1 },
};

static void android_server_SystemServer_init1(JNIEnv* env, jobject clazz)
{
    system_init();
}

extern "C" int system_init();

在system_init.cpp文件中找到system_init()方法

extern "C" status_t system_init()
{
    //這個(gè)方法里主要是開啟硬件管理服務(wù)
    SensorService::instantiate();
    AudioFlinger::instantiate();
    MediaPlayerService::instantiate();
    CameraService::instantiate();

    //執(zhí)行SystemServer類中的init2()方法
    runtime->callStatic("com/android/server/SystemServer", "init2");
}

回到SystemServer類中的init2()方法

public static final void init2() {
    //創(chuàng)建系統(tǒng)服務(wù)線程
    Thread thr = new ServerThread();
    thr.setName("android.server.ServerThread");
    thr.start();
}

6盏触、在ServerThread類中的run()方法中,開啟系統(tǒng)的其他服務(wù)

//準(zhǔn)備消息輪詢器
Looper.prepare();

//啟動(dòng)大量的系統(tǒng)服務(wù)并把其逐一添加至ServiceManager
ServiceManager.addService(Context.WINDOW_SERVICE, wm);

//調(diào)用ActivityManagerService類中的systemReady()方法块饺,準(zhǔn)備創(chuàng)建第一個(gè)activity
((ActivityManagerService)ActivityManagerNative.getDefault()).systemReady(new Runnable() {});

7赞辩、在ActivityManagerService.java中,找到systemReady()方法

public ActivityStack mMainStack;

public void systemReady(final Runnable goingCallback) {
    //啟動(dòng)laucher
    mMainStack.resumeTopActivityLocked(null);
}

在ActivityStack.java中找到resumeTopActivityLocked()方法

final boolean resumeTopActivityLocked(ActivityRecord prev) {
    ActivityRecord next = topRunningActivityLocked(null);

    //判斷棧頂是否有activity授艰,沒(méi)有的話直接啟動(dòng)laucher
    if (next == null) {
    // There are no more activities!  Let's just start up the Launcher...
        if (mMainStack) {
            return mService.startHomeActivityLocked();
        }
    }
}

至此辨嗽,Laucher已經(jīng)被啟動(dòng),Android系統(tǒng)啟動(dòng)完成淮腾;

聲明:本文只做學(xué)習(xí)交流糟需,歡迎大家提出各類問(wèn)題屉佳,讓我們共同進(jìn)步!V扪骸武花!

最后附上時(shí)序圖一張


Android系統(tǒng)的啟動(dòng)時(shí)序圖.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市诅诱,隨后出現(xiàn)的幾起案子髓堪,更是在濱河造成了極大的恐慌,老刑警劉巖娘荡,帶你破解...
    沈念sama閱讀 221,888評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件干旁,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡炮沐,警方通過(guò)查閱死者的電腦和手機(jī)争群,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,677評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)大年,“玉大人换薄,你說(shuō)我怎么就攤上這事∠枋裕” “怎么了轻要?”我有些...
    開封第一講書人閱讀 168,386評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)垦缅。 經(jīng)常有香客問(wèn)我冲泥,道長(zhǎng),這世上最難降的妖魔是什么壁涎? 我笑而不...
    開封第一講書人閱讀 59,726評(píng)論 1 297
  • 正文 為了忘掉前任凡恍,我火速辦了婚禮,結(jié)果婚禮上怔球,老公的妹妹穿的比我還像新娘嚼酝。我一直安慰自己,他們只是感情好竟坛,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,729評(píng)論 6 397
  • 文/花漫 我一把揭開白布闽巩。 她就那樣靜靜地躺著,像睡著了一般担汤。 火紅的嫁衣襯著肌膚如雪又官。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,337評(píng)論 1 310
  • 那天漫试,我揣著相機(jī)與錄音六敬,去河邊找鬼。 笑死驾荣,一個(gè)胖子當(dāng)著我的面吹牛外构,可吹牛的內(nèi)容都是我干的普泡。 我是一名探鬼主播,決...
    沈念sama閱讀 40,902評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼审编,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼撼班!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起垒酬,我...
    開封第一講書人閱讀 39,807評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤砰嘁,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后勘究,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體矮湘,經(jīng)...
    沈念sama閱讀 46,349評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,439評(píng)論 3 340
  • 正文 我和宋清朗相戀三年口糕,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了缅阳。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,567評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡景描,死狀恐怖十办,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情超棺,我是刑警寧澤向族,帶...
    沈念sama閱讀 36,242評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站棠绘,受9級(jí)特大地震影響件相,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜弄唧,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,933評(píng)論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望霍衫。 院中可真熱鬧候引,春花似錦、人聲如沸敦跌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,420評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)柠傍。三九已至麸俘,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間惧笛,已是汗流浹背从媚。 一陣腳步聲響...
    開封第一講書人閱讀 33,531評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留患整,地道東北人拜效。 一個(gè)月前我還...
    沈念sama閱讀 48,995評(píng)論 3 377
  • 正文 我出身青樓喷众,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親紧憾。 傳聞我的和親對(duì)象是個(gè)殘疾皇子到千,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,585評(píng)論 2 359

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