Android系统启动流程源码分析

用Source Insight来追踪Android系统启动流程的源码,并将我认为重要的源码进行分析

1、当系统引导程序启动Linux内核,内核会记载各种数据结构和驱动程序,加载完毕之后,Android系统开始启动并加载第一个用户级别的进程:Init.c(system\core\init)

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

2、执行配置文件init.rc(system\core\rootdir)中定义好的指令,进行环境初始化;执行了很多bin指令,来启动系统服务

//启动孵化器进程,执行app_process(一个编译好的可执行文件)
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[])
{
    //启动一个系统服务:ZygoteInit
  runtime.start("com.android.internal.os.ZygoteInit",startSystemServer);
}

4、在ZygoteInit.java中,查看main()方法

public static void main(String argv[]) {
    //预加载Android系统所需要的类
    preloadClasses();
    if (argv[1].equals("true")) {
        //调用方法开启系统服务
        startSystemServer();
     }
}

preloadClasses(),加载Android运行时环境

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

private static void preloadClasses() {
    //用类加载器,根据文件名,加载资源作为一个输入流
    InputStream is = ZygoteInit.class.getClassLoader().getResourceAsStream(PRELOADED_CLASSES);
    BufferedReader br = new BufferedReader(new InputStreamReader(is), 256);
    String line;
    //一行一行的读取全包名
    while ((line = br.readLine()) != null) {
    //根据全包名加载类
      Class.forName(line);
    }  

}

startSystemServer(),这个方法开启系统服务

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服务
     "com.android.server.SystemServer",
};

5、启动SystemServer服务

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

public static void main(String[] args) {
    //加载C库
    System.loadLibrary("android_servers");
    //执行C库里的init1方法
    init1(args);
}

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

static JNINativeMethod gMethods[] = {
    /* name, signature, funcPtr */
    //给init1方法映射一个指针,最后调用了system_init()方法,而system_init()没有方法体
    { "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()
{
    //这个方法里主要是开启硬件管理服务
    SensorService::instantiate();
    AudioFlinger::instantiate();
    MediaPlayerService::instantiate();
    CameraService::instantiate();

    //执行SystemServer类中的init2()方法
    runtime->callStatic("com/android/server/SystemServer", "init2");
}

回到SystemServer类中的init2()方法

public static final void init2() {
    //创建系统服务线程
    Thread thr = new ServerThread();
    thr.setName("android.server.ServerThread");
    thr.start();
}

6、在ServerThread类中的run()方法中,开启系统的其他服务

//准备消息轮询器
Looper.prepare();

//启动大量的系统服务并把其逐一添加至ServiceManager
ServiceManager.addService(Context.WINDOW_SERVICE, wm);

//调用ActivityManagerService类中的systemReady()方法,准备创建第一个activity
((ActivityManagerService)ActivityManagerNative.getDefault()).systemReady(new Runnable() {});

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

public ActivityStack mMainStack;

public void systemReady(final Runnable goingCallback) {
    //启动laucher
    mMainStack.resumeTopActivityLocked(null);
}

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

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

    //判断栈顶是否有activity,没有的话直接启动laucher
    if (next == null) {
    // There are no more activities!  Let's just start up the Launcher...
        if (mMainStack) {
            return mService.startHomeActivityLocked();
        }
    }
}

至此,Laucher已经被启动,Android系统启动完成;

声明:本文只做学习交流,欢迎大家提出各类问题,让我们共同进步!!!

最后附上时序图一张


Android系统的启动时序图.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,056评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,842评论 2 378
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,938评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,296评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,292评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,413评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,824评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,493评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,686评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,502评论 2 318
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,553评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,281评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,820评论 3 305
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,873评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,109评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,699评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,257评论 2 341

推荐阅读更多精彩内容