Android Framework系列2 系统启动

Android的系统启动

  • Android有哪些比较主要的系统进程?
  • 这些系统进程是如何启动的?
  • 系统进程启动之后做了哪些事?



主要的系统进程
首先还是从启动配置文件init.rc中查找,这个文件中定义了很多Service,这些Service其实就是要单独启动的系统服务进程,以下我列了几个我们比较熟悉的。

service zygote /system/bin/app_process …
service servicemanager /system/bin/servicemanager …
service surfaceflinger /system/bin/surfaceflinger … 
service media /system/bin/mediaserver …

由init进程启动的几个比较主要的进程有Zygote,Servicemanager,surfaceflinger;Android系统进程中还有一个比较主要的进程SystemServer,这个进程其实是由Zygote进程创建的。关于Zygote相关可查考 Zygote启动;别的主要系统服务详细介绍待写。



SystemServer
书接上回 Zygote启动;可以看到,Zygote通过forkSystemServer来创建是SystemServer的进程,代码如下:

          // 代码来自Android23中:ZygoteInit.java
private static boolean startSystemServer(String abiList, String socketName)
            throws MethodAndArgsCaller, RuntimeException {
          ......
         /* Request to fork the system server process */
          pid = Zygote.forkSystemServer(...);
          ......
       /* For child process */
        if (pid == 0) {
            if (hasSecondZygote(abiList)) {
                waitForSecondaryZygote(socketName);
            }

            handleSystemServerProcess(parsedArgs);
        }
}

1.通过这个forkSystemServer来创建是SystemServer的进程。
2 创建SystemServer进程后,在这个进程里面执行这个handleSystemServerProcess,就是SystemServer启动的具体逻辑。

// 代码来自Android23中:ZygoteInit.java
private static void handleSystemServerProcess(...){
      RuntimeInit.zygoteInit(......);
}
// 代码来自Android23中:RuntimeInit.java
public static final void zygoteInit(...){
    commonInit();
    nativeZygoteInit();
    applicationInit(targetSdkVersion, argv, classLoader);
}

handleSystemServerProcess主要代码就简单贴贴:
1 nativeZygoteInit这个函数的,主要是用于启用Binder机制,且启动了一个binder线程,因为Systemserver有很多系统服务都需要跟别的进程通信,比如我们的应用进程,比如ServiceManager等等。
2 applicationInit这个函数呢主要是调用SystemServer这个Java类的入口函数。

总结下上面的代码:

  • Zygote创建SystemServer的进程
  • 在SystemServer的进程中启用Binder机制
  • 跳转到SystemServer.java的main方法



SystemServer.java

public static void main(String[] args) {
        new SystemServer().run();
    }
// 代码来自Android23中:SystemServer.java
private void run() {
    Looper.prepareMainLooper();
    System.loadLibrary("android_servers");
    createSystemContext();
    startBootstrapServices();
    startCoreServices();
    startOtherServices();
    Looper.loop();
}
  • 为主线程创建一个Loop
  • 加载这么一个共享库,系统服务它的native代码
  • 创建一个系统上下文
  • 分三批分别来加载系统服务
  • 进入Loop循环




下面看两个问题:

  • 系统服务要怎么发布才能让应用进程可见?
  • 系统服务究竟跑在什么线程?

系统服务发布


// 代码来自Android23中:SystemService.java
public abstract class SystemService {
   protected final void publishBinderService(String name, IBinder service) {
        publishBinderService(name, service, false);
    }
protected final void publishBinderService(String name, IBinder service,
            boolean allowIsolated) {
        ServiceManager.addService(name, service, allowIsolated);
    }
}

publishBinderService这个函数把系统服务它的binder注册到了ServiceManager中。



系统服务跑在什么线程

1). 有的服务有自己独有的工作线程,比如说咱们比较熟悉的AMS,PMS,还有PackageManagerService。
2).还有一些公用的工作线程:DisplayThread,FgThread,IoThread,UiThread,从名字上就能知道职责是什么;其中UiThread负责UI显示的,从这可以看出UI刷新不一定得再主线程,子线程也是可以的;还有一种就是Binder线程,也就是应用跨进程调用过来时是在Binder线程中的。




如何解决SystemServer启动过程中的服务依赖?

SystemServer启动过程中服务的这个相互依赖是怎么解决了,什么叫相互依赖呢?就是服务A需要用到服务B的一些东西,服务B又要用到服务C一些东西,那这样就形成了一个依赖关系,像SystemServer里面系统服务大概有七八十个了,你要完全解决这些服务之间错综复杂的依赖关系的其实不是一件容易的事,那么安卓他是怎么解决的呢?

  • 分批启动
    也就是前面源码中的三个start***Service(),比较基础的放前面,比如说AMS,PMS,PKMS等等,但很多service都需要依赖这几个Service。

  • 分阶段启动
    就是给启动分成不同的阶段,每到了一个阶段的就去通知当前已经启动了的service告诉他们现在到了什么阶段了,哪些资源又可以用;service就可以去做一些这个阶段里面可以做的初始化。




桌面的启动

  • 在AMS服务就绪的时候会调用systemReady函数
// 代码来自Android23中:ActivityManagerService.java
public void systemReady(final Runnable goingCallback) {
      ......
      startHomeActivityLocked(mCurrentUserId, "systemReady");
}
// 代码来自Android23中:ActivityManagerService.java
boolean startHomeActivityLocked(int userId, String reason) {
      Intent intent = getHomeIntent();
      ......
      mStackSupervisor.startHomeActivity(intent, aInfo, reason);
}

桌面其实你可以把它看成是一个单独的应用,系统级的应用;我们这是启动这个桌面的Activity。在Activity的onCreate里面呢,会启用一个LoaderTask,他会去向这个packagemanager去查询所有当前已经安装了这些应用,查询到了之后就把这些应用显示在桌面上,就是一个图标的方式,显示在桌面上,当我们点击了这些应用的图标之后呢,就会去启动这个应用的launchAcitivity

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

推荐阅读更多精彩内容