技术库 > Java

Android系统启动过程

技术库:tec.5lulu.com

from:tec.5lulu.com

       首先Android框架架构图:

Android系统启动过程,by 5lulu.com

       Linux内核启动之后就到Android Init进程,进而启动Android相关的服务和应用。

       启动的过程如下图所示:

Android系统启动过程,by 5lulu.com

       下面将从Android4.0源码中,和网络达人对此的总结中,对此过程加以学习了解和总结,

1 Init进程的启动

       init进程,它是一个由内核启动的用户级进程。内核自行启动(已经被载入内存,开始运行,并已初始化所有的设备驱动程序和数据结构等)之后,就通过启动一个用户级程序init的方式,完成引导进程。init始终是第一个进程。

       启动过程就是代码init.c中main函数执行过程:systemcoreinitinit.c

       在函数中执行了:文件夹建立,挂载,rc文件解析,属性设置,启动服务,执行动作,socket监听……

       下面看两个重要的过程:rc文件解析和服务启动。

1 rc文件解析

       .rc文件是Android使用的初始化脚本文件 (System/Core/Init/readme.txt中有描述:

four broad classes of statements which are Actions, Commands, Services, and Options.)

       其中Command 就是系统支持的一系列命令,如:export,hostname,mkdir,mount,等等,其中一部分是 linux 命令,

还有一些是 android 添加的,如:class_start <serviceclass>: 启动服务,class_stop <serviceclass>:关闭服务,等等。

       其中Options是针对 Service 的选项的。

       系统初始化要触发的动作和要启动的服务及其各自属性都在rc脚本文件中定义。 具体看一下启动脚本:systemcorerootdirinit.rc

      在解析rc脚本文件时,将相应的类型放入各自的List中:

systemcoreinitInit_parser.c  :init_parse_config_file( )存入到

action_queue、   action_list、 service_list中,解析过程可以看一下parse_config函数,类似状态机形式挺有意思。

       这其中包含了服务:adbd、servicemanager、vold、ril-daemon、debuggerd、surfaceflinger、zygote、media……

2 服务启动

      文件解析完成之后将service放入到service_list中。system/core/init/init.c中:

int main(){
     ……
      for(;;){
             execute_one_command();
             restart_processes();
             for (i = 0; i < fd_count; i++) {
           if (ufds[i].revents == POLLIN) {
               if (ufds[i].fd == get_property_set_fd())
                   handle_property_set_fd();
               else if (ufds[i].fd == get_keychord_fd())
                   handle_keychord();
               else if (ufds[i].fd == get_signal_fd())
                   handle_signal();
           }
       }
      }
}

       循环调用service_start,将状态SVC_RESTARTING启动, 将启动后的service状态设置为SVC_RUNNING。

pid=fork();
execve();

       在消息循环中:Init进程执行了Android的Command,启动了Android的NativeService,监听Service的变化需求,Signal处理。

       Init进程是作为属性服务(Property service),维护这些NativeService。

2 ServiceManager启动

      在.rc脚本文件中zygote的描述:

service servicemanager /system/bin/servicemanager

class core

user system

group system

critical

onrestart restart zygote

onrestart restart media

onrestart restart surfaceflinger

onrestart restart drm

      ServiceManager用来管理系统中所有的binder service,不管是本地的c++实现的还是java语言实现的都需要

       这个进程来统一管理,最主要的管理就是,注册添加服务,获取服务。所有的Service使用前都必须先在servicemanager中进行注册。

do_find_service( )

do_add_service( )

svcmgr_handler( )

       代码位置:frameworksbasecmdsservicemanagerService_manager.c

3 Zygote进程的启动

       Zygote这个进程是非常重要的一个进程,Zygote进程的建立是真正的Android运行空间,初始化建立的Service都是Navtive service.

(1) 在.rc脚本文件中zygote的描述:

service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
  class main
  socket zygote stream 666
  onrestart write /sys/android_power/request_state wake
  onrestart write /sys/power/state on
  onrestart restart media
  onrestart restart netd        参数:--zygote --start-system-server

       代码位置:frameworks/base/cmds/app_process/app_main.cpp

      上面的参数在这里就会用上,决定是否要启动和启动那些进程。

int main( ){
      AppRuntime runtime;
      if (zygote) {
             runtime.start("com.android.internal.os.ZygoteInit",
               startSystemServer ? "start-system-server" : "");
      }
}
class AppRuntime : public AndroidRuntime{};

(2) 接着到了AndroidRuntime类中:

frameworksbasecorejniAndroidRuntime.cpp
void start(const char* className, const char* options){
      // start the virtual machine Java在虚拟机中运行的
      JNIEnv* env;
      if (startVm(&mJavaVM, &env) != 0) {
             return;
      }
      //向刚刚新建的虚拟机注册JNI本地接口
      if (startReg(env) < 0) {
             return;
      }
    // jni 调用 java 方法,获取对应类的静态main方法
    jmethodID startMeth = env->GetStaticMethodID(startClass,
        "main","([Ljava/lang/String;)V");
      // jni调用 java方法,调用到ZygoteInit类的main函数
      jclass startClass = env->FindClass(className);
      env->CallStaticVoidMethod(startClass, startMeth, strArray);
}

       到了ZygoteInit.java中的静态main函数中,从C++ ——》JAVA

(3)ZygoteInit

      真正Zygote进程:             frameworksbasecorejavacomandroidinternalosZygoteInit.java

public static void main(String argv[]) {
      //Registers a server socket for zygote command connections
      registerZygoteSocket();
      //Loads and initializes commonly used classes and
      //used resources that can be shared across processes
      preload();
      // Do an initial gc to clean up after startup
      gc();
      if (argv[1].equals("start-system-server")) {
             startSystemServer();
      }
      /**
      * Runs the zygote process's select loop. Accepts new connections as
      * they happen, and reads commands from connections one spawn-request's
      * worth at a time.
      */
      runSelectLoopMode();    //loop中
      /**
      * Close and clean up zygote sockets. Called on shutdown and on the
      * child's exit path.
      */
      closeServerSocket();
}

      Zygote就建立好了,利用Socket通讯,接收请求,Fork应用程序进程,进入Zygote进程服务框架中。

4 SystemServer启动

(1)在Zygote进程进入循环之前,调用了startSystemServer( );

private static boolean startSystemServer(){
      /* Request to fork the system server process 孵化新的进程 */
    ZygoteConnection.Arguments parsedArgs = null;
      pid = Zygote.forkSystemServer(
             parsedArgs.uid, parsedArgs.gid,
             parsedArgs.gids,
             parsedArgs.debugFlags,
             null,
             parsedArgs.permittedCapabilities,
             parsedArgs.effectiveCapabilities);
             /* For child process 对新的子进程设置 */
      if (pid == 0) {
             handleSystemServerProcess(parsedArgs);
      }
}
void handleSystemServerProcess(parsedArgs){
      closeServerSocket();
      //"system_server"
      Process.setArgV0(parsedArgs.niceName);
      //Pass the remaining arguments to SystemServer.
    RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion,
      parsedArgs.remainingArgs);
      /* should never reach here */
}

(2)RuntimeInit中:      frameworksbasecorejavacomandroidinternalosRuntimeInit.java

//The main function called when started through the zygote process.
void zygoteInit(int targetSdkVersion, String[] argv){
       applicationInit(targetSdkVersion, argv);
}
void applicationInit(int targetSdkVersion, String[] argv){
   // Remaining arguments are passed to the start class's static main
   invokeStaticMain(args.startClass, args.startArgs);
}
void invokeStaticMain(String className, String[] argv){
   Class<?> cl;
   cl = Class.forName(className);
   //获取SystemServer的main方法,抛出MethodAndArgsCaller异常
   Method m;
   m = cl.getMethod("main", new Class[] { String[].class });
   int modifiers = m.getModifiers();
   throw new ZygoteInit.MethodAndArgsCaller(m, argv);
}

(3)从startSystemServer开始执行并没有去调用SystemServer的任何方法,

只是通过反射获取了main方法,付给了MethodAndArgsCaller,并抛出了MethodAndArgsCaller异常。

       此异常是在哪里处理的呢?

      回到startSystemServer( )函数的调用处:

      在ZygoteInit的main函数中:

public static void main(String argv[]) {
      try {
             ……
             if (argv[1].equals("start-system-server")) {
                 startSystemServer();       //这里如果抛出异常,跳过下面流程
             }        
        runSelectLoopMode();    //loop中
             ……
      } catch (MethodAndArgsCaller caller) {
             caller.run();        //处理的异常
      }
}

       如果startSystemServer抛出了异常,跳过执行ZygoteInit进程的循环,这是怎么回事呢?

       在startSystemServer中异常是由handleSystemServerProcess抛出,而

pid = Zygote.forkSystemServer( )

/* For child process 仅对新的子进程设置 */

if (pid == 0) {

handleSystemServerProcess(parsedArgs);

}

// Zygote.forkSystemServer根据参数fork 出一个子进程,若成功调用,则返回两次:

一次返回的是 zygote 进程的 pid ,值大于0;一次返回的是子进程 pid,值等于0否则,出错返回-1;

caller.run();

MethodAndArgsCaller run函数:调用前面所提到的

//SystemServer main方法

m = cl.getMethod("main", new Class[] { String[].class });

       启动了进程SystemServer。

(4)SystemServer的执行 init1( )              //frameworksbaseservicesjavacomandroidserverSystemServer.java

public static void main(String[] args) {
        System.loadLibrary("android_servers");    
        /*
        * This method is called from Zygote to initialize the system.
        * This will cause the native services (SurfaceFlinger, AudioFlinger, etc..)
        * to be started. After that it will call back
        * up into init2() to start the Android services.
        */
        init1(args);    //native 完了回调init2( )
  }
//init1: frameworks/base/services/jni/com_android_server_SystemServer.cpp:: android_server_SystemServer_init1( )
  中调用:system_init
extern "C" status_t system_init()
{
      sp<ProcessState> proc(ProcessState::self());
      sp<IServiceManager> sm = defaultServiceManager();
      //启动SurfaceFlinger 和传感器
      property_get("system_init.startsurfaceflinger", propBuf, "1");
      SurfaceFlinger::instantiate();
      property_get("system_init.startsensorservice", propBuf, "1");
      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.
      AndroidRuntime* runtime = AndroidRuntime::getRuntime();
      //回调 com.android.server.SystemServer init2 方法      
      JNIEnv* env = runtime->getJNIEnv();
      jclass clazz = env->FindClass("com/android/server/SystemServer");
      jmethodID methodId = env->GetStaticMethodID(clazz, "init2", "()V");
      env->CallStaticVoidMethod(clazz, methodId);  
      //启动线程池 做为binder 服务
      ProcessState::self()->startThreadPool();
      IPCThreadState::self()->joinThreadPool();
      return NO_ERROR;
}

ProcessState:

       每个进程在使用binder 机制通信时,均需要维护一个ProcessState 实例来描述当前进程在binder 通信时的binder 状态。

ProcessState 有如下2 个主要功能:

       1. 创建一个thread, 该线程负责与内核中的binder 模块进行通信,称该线程为Pool thread ;

       2. 为指定的handle 创建一个BpBinder 对象,并管理该进程中所有的BpBinder 对象。

Pool thread:

       在Binder IPC 中,所有进程均会启动一个thread 来负责与BD 来直接通信,也就是不停的读写BD ,

       这个线程的实现主体是一个IPCThreadState 对象,下面会介绍这个类型。

       下面是Pool thread 的启动方式:

ProcessState::self()->startThreadPool();

IPCThreadState :

       IPCThreadState 也是以单例模式设计的。由于每个进程只维护了一个ProcessState 实例,同时ProcessState 只启动一个Pool thread ,

       也就是说每一个进程只会启动一个Pool thread ,因此每个进程则只需要一个IPCThreadState 即可。

Pool thread 的实际内容则为:

IPCThreadState::self()->joinThreadPool();

(5)SystemServer的执行 init2( )

public static final void init2() {  
    //建立线程来处理
      Thread thr = new ServerThread();      
      thr.setName("android.server.ServerThread");
      thr.start();
}
//看看线程ServerThread里面都做了什么事情?
public void run() {
   addBootEvent(new String("Android:SysServerInit_START"));
   Looper.prepare();
   android.os.Process.setThreadPriority(
   android.os.Process.THREAD_PRIORITY_FOREGROUND);
   //初始化服务,创建各种服务实例,如:电源、网络、Wifi、蓝牙,USB等,
  //初始化完成以后加入到 ServiceManager中,
   //事我们用 Context.getSystemService (String name) 才获取到相应的服务
   PowerManagerService power = null;
   NetworkManagementService networkManagement = null;
   WifiP2pService wifiP2p = null;
   WindowManagerService wm = null;
   BluetoothService bluetooth = null;
   UsbService usb = null;
   NotificationManagerService notification = null;
   StatusBarManagerService statusBar = null;
   ……
   power = new PowerManagerService();
   ServiceManager.addService(Context.POWER_SERVICE, power);
   ……
   // ActivityManagerService作为ApplicationFramework最重要的服务
   ActivityManagerService.setSystemProcess();
   ActivityManagerService.installSystemProviders();
   ActivityManagerService.self().setWindowManager(wm);  
  // We now tell the activity manager it is okay to run third party
  // code.  It will call back into us once it has gotten to the state
  // where third party code can really run (but before it has actually
  // started launching the initial applications), for us to complete our
  // initialization.
  //系统服务初始化准备就绪,通知各个模块
   ActivityManagerService.self().systemReady(new Runnable() {
          public void run() {
                 startSystemUi(contextF);
                 batteryF.systemReady();
                 networkManagementF.systemReady();
                 usbF.systemReady();
                 ……
                 // It is now okay to let the various system services start their
                 // third party code...
                 appWidgetF.systemReady(safeMode);
                 wallpaperF.systemReady();
          }
   });
   //
   //BOOTPROF
   addBootEvent(new String("Android:SysServerInit_END"));
   Looper.loop();
}

       到这里系统ApplicationFramework层的XxxServiceManager准备就绪,可以开始跑上层应用了,我们的第一个上层应用HomeLauncher。

       HomeActivity又是如何启动的呢?

       Activity的启动必然和ActivityManagerService有关,我们需要去看看

       ActivityManagerService.systemReady( )中都干了些什么。

5 Home界面启动

public void systemReady(final Runnable goingCallback) {
    ……
    //ready callback
      if (goingCallback != null)
             goingCallback.run();
      synchronized (this) {
             // Start up initial activity.
             // ActivityStack mMainStack;
             mMainStack.resumeTopActivityLocked(null);
      }
……
}
final boolean resumeTopActivityLocked(ActivityRecord prev) {
  // Find the first activity that is not finishing.
  ActivityRecord next = topRunningActivityLocked(null);
  if (next == null) {
    // There are no more activities!  Let's just start up the
    // Launcher...
    if (mMainStack) {
      //ActivityManagerService mService;
      return mService.startHomeActivityLocked();
    }
  }
  ……
}

       然后就启动了Home界面,完成了整个Android启动流程。

       整个过程如下:

Android系统启动过程,by 5lulu.com

Android系统启动过程


本文链接 http://tec.5lulu.com/detail/110kzn1h9n13l8y6a.html

我来评分 :7
2

转载注明:转自5lulu技术库

本站遵循:署名-非商业性使用-禁止演绎 3.0 共享协议

www.5lulu.com