【Android话题-2.2系统服务】说说Android系统的启动

Source

考察内容:

  • Android有哪些主要的系统进程?
  • 这些系统进程是怎么启动的?
  • 进程启动之后主要做了些什么事?

系统进程

  • zygote
  • SystemServer
  • servicemanager
  • hwservicemanager
  • surfaceflinger

重要进程的启动

Zygote的启动流程

  • init进程fork出zygote进程
  • 启动虚拟机,注册jni函数
  • 预加载系统资源
  • 启动SystemServer
  • 进入Socket Loop

Zygote的工作流程

在启动流程的最后一部,zygote进入Socket Loop循环,一旦socket有消息就会调用runOnce函数,runOnce函数如下:

boolean runOnce(){
  //读取参数列表
  String[] args = readArgumentList();
  //创建进程
  int pid = Zygote.forkAndSpecialize(...);
  if (pid == 0){ //子进程逻辑
    handleChildProc(parsedArgs, ..);
    //should never get here, the child is expected to either
    //throw ZygoteInit.MethodAndArgsCaller or exec().
    return true;
  }else{ //父进程逻辑
    return handleParentProc(pid, ...);
  }
}

SystemServer是怎么启动的?

private static boolean forkSystemServer(...){
  String args[] = {
    ...
    "com.android.server.SystemServer",
  };
  //创建SystemServer进程
  int pid = Zygote.forkSystemServer(...);
  if (pid == 0){
    //在子进程中执行SystemServer启动的具体逻辑
    handleSystemServerProcess(parsedArgs);
  }
  return true;
}
void handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) {
  ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
}

void zygoteInit(String[] argv, ...){
  //一些常规的初始化
  RuntimeInit.commonInit();
  //启用binder机制,并启动binder线程
  ZygoteInit.nativeZygoteInit();
  //调用java类的入口函数————本例中其实就是SystermServer.java
  RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}

virtual void onZygoteInit(){
  sp<ProcessState> proc = ProcessState::self();
  proc->startThreadPool();
}

void applicationInit(...){
  invokeStaticMain(args, ...);
}

SystemServer.java::main

public static void main(String[] args){
  new SystemServer().run();
}

private void run(){
  //为主线程创建Looper
  Looper.prepareMainLooper();
  //加载共享库
  System.loadLibrary("android_servers")
  //创建系统上下文
  createSystemContext();
  //将系统服务分三批启动
  startBootstrapServices();
  startCoreServices();
  startOtherServices();
  //进入主循环
  Looper.loop();
}

看两个问题:

  • 系统服务是怎么启动的?
  • 怎么解决系统服务之间的互相依赖?

系统服务是怎么启动的

怎么发布服务服务?

答案是:把系统服务的binder注册到ServiceManager

    void publishBinderService(String name, IBinder service) {
        publishBinderService(name, service, false);
    }
    
    void publishBinderService(String name, IBinder service,
            boolean allowIsolated) {
        
        ServiceManager.addService(name, service, allowIsolated);
    }

系统服务跑在什么线程?

  • 主线程?
  • 工作线程? (私有线程,公有线程:DisplayThread/FgThread/IoThread/UiThread)
  • binder线程?

课堂作业

  • 为什么系统服务不都跑在binder线程里?
  • 为什么系统服务不都跑在自己私有的工作线程里?
  • 跑在binder线程和跑在工作线程,如何取舍?

怎么解决系统服务之间的互相依赖?

什么是服务之间的依赖?
如:服务A要用到服务B的东西,服务B要用到服务C的东西

  • 分批启动 (把比较基础的服务,如AMS/PMS/PKMS等放在前面)
  • 分阶段启动 阶段1 阶段2 阶段3 …
    (把启动分成不同的阶段,每到一个阶段就通知当前已经启动的服务,告诉它们现在到了什么阶段了,哪些资源又可以用了)

桌面的启动

public void systemReady(final Runnable goingCallback){
  ……
  startHomeActivityLocked(mCurrentUserId, "systemReady"){
    mLoaderTask = new LoaderTask(mApp.getContext(), loadFlags){
      mPm.queryIntentActivityesAsUser()
    }
  }
  ……
}


回归:说说Android系统的启动流程?

  • zygote是怎么启动的?
  • systemServer是怎么启动的?
  • 系统服务是怎么启动的?
发布了101 篇原创文章 · 获赞 27 · 访问量 10万+