Android系统启动及zygote总结

1.Android系统框架图


2.Android系统启动框图 





------------------> Init进程启动:

         system\core\init\init.c:函数执行文件夹建立,挂载,rc文件解析,属性设置,启动服务,执行动作,socket监听……

 Key Process:

1) rc文件解析----

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

four broad classes of statements which are ActionsCommandsServices, and Options.)

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

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

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

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

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

  \system\core\init\Init_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\builtins.c

       Service的启动是在do_class_start函数中完成:

int do_class_start(int nargs, char **args)
{
    service_for_each_class(args[1], service_start_if_not_disabled);
    return 0;
}

 

遍历所有名称为classname,状态不为SVC_DISABLED的Service启动

 

复制代码
void service_for_each_class(const char *classname,
                            void (*func)(struct service *svc))
{
       ……
}

static void service_start_if_not_disabled(struct service *svc)
{
    if (!(svc->flags & SVC_DISABLED)) {
        service_start(svc, NULL);
    }
}
复制代码

 

 

do_class_start对应的命令:

 

  KEYWORD(class_start, COMMAND, 1, do_class_start)

 

init.rc文件中搜索class_start:class_start main 、class_start core、……

 

  main、core即为do_class_start参数classname

 

init.rc文件中Service class名称都是main:

 

       service drm /system/bin/drmserver

 

    class main

 

  service surfaceflinger /system/bin/surfaceflinger

 

       class main

 

于是就能够通过main名称遍历到所有的Service,将其启动。

do_class_start调用:

       init.rc中

    on boot  //action

      class_start core    //执行command 对应 do_class_start

          class_start main

 

Init进程main函数中:

 

system/core/init/init.c中:

复制代码
int main(){

     //挂在文件

       //解析配置文件:init.rc……

       //初始化化action queue

     ……
       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。

 ------------------------------->  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( )

  代码位置:frameworks\base\cmds\servicemanager\Service_manager.c



-------------------->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类中:

frameworks\base\core\jni\AndroidRuntime.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进程:

              frameworks\base\core\java\com\android\internal\os\ZygoteInit.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进程服务框架中。




-------------------->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中:

       frameworks\base\core\java\com\android\internal\os\RuntimeInit.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( )

              //frameworks\base\services\java\com\android\server\SystemServer.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( )中都干了些什么。



-------------------->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启动流程。

      整个过程如下:

  


3.Android上层应用启动流程

   1.说明
应用的启动过程通常是通过startActivity函数,无论是在应用中调其它应用还是在桌面(桌面是Launcher应用)上点击,最终都将通过这个函数启动进程或者界面,下面以分析代码的方式,介绍它具体的工作过程

   2. 过程

1)        packages/apps/Launcher2/src/com/android/launcher.java

在应用或桌面上启动应用,例如桌面应用的启动由于中调用函数流程startActivitySafely() -> startActivity()

2)        frameworks/base/core/java/android/app/Activity.java:startActivity()
Activity.java继承了Context.java,并实现了它的startActivity() -> startActivityForResult() -> execStartActivity()

3)        frameworks/base/core/java/android/app/Instrumentation.java:execStartActivity()
execStartActivity利用IntentFilter得到具体Activity,并调用了更下层的startActivity

4)        frameworks/base/core/java/android/app/ActivityManagerNative.java
ActivityManagerProxy.startActivity()
IBinder.transact(….); //mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);

                                 // 此句代码很重要,它会把以上所有数据,跨进程传递给ActivityManagerService类中onTrasact 方法处理。

                                // 调用父类ActivityManagerNative中的onTrasact()方法


它通过Binder的方式与ActivityManagerService.java通讯,并发送启动请求

5)        frameworks/base/core/java/android/os/Binder.java:execTransact()
Binder消息转递的实现,用于用户应用与后台服务的通讯

6)        frameworks/base/services/java/com/android/server/am/ActivityManagerService.java
onTransact();

startActivity() -> startActivityMayWait() - >startActivityLocked()->resumeTopActivityLocked()->startSpecificActivityLocked()->startProcessLocked () 

开启新线程

7)        frameworks/base/core/java/android/os/Process.java的函数start为入口 调用 startViaZygote -》zygoteSendArgsAndGetPid,通过socket发给zygote进程

8)        frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
告知虚拟机新建进程,此时会将要建立的进程名,用户名,组名一并传给虚拟机,以建立进程

通过调用Runonce 调用folkAndSpecialize 使用Native 函数Dalvik_dalvik_system_Zygote_forkAndSpecialize(dalvik/vm/native/dalvik_system_Zygote.c)

9)        dalvik/libcore/dalvik/src/main/java/dalvik/system/Zygote.java
虚拟机处理

10)     dalvik/vm/native/dalvik_system_Zygote.c (forkAndSpecializeCommon)
虚拟机处理

至此建立了andorid应用程序跑的进程,后面将执行此进程,新进程从android.app.ActivityThread.main开始运行。这里就是一般意义上的程序入口点,类似于C的main函数

thread.attach(false);     //  frameworks/base/core/java/android/app/ActivityThread.java

attachApplication();      // frameworks/base/services/java/com/android/server/am/ActivityManagerService.java

   --------realStartActivityLocked() @ActivityManagerService // 此方法是进入真正启动一个Activity流程


   --------scheduleLaunchActivity () @ActivityThread  @ApplicationThread  // 此方法进入到

                 ApplicationThreadNative提供的服务,也就是到ActivityThread的内部类ApplicationThread类中,

 scheduleLaunchActivity方法定义如下:


           scheduleLaunchActivity (Intent intent, IBinder token, int ident......) {

              ActivityRecord r = new ActivityRecord() ; // 为此Activity定义一个客户端实例

              ....

             queueOrSendMessage(H.LAUNCH_ACTIVITY, r); // 把启动Activity的消息传给一个内部类(H)来处理

              // H类是一个Handler,


         }


   --------------handleLaunchActivity   @ ActivityThread

   --------------performLaunchActivity  @ActivityThread   // 此方法开始具体创建Activity,并调用其生命周期


   此方法定义如下 :

         private final Activity performLauchActivity(ActivityRecord r, Intent customIntent)  {

         .....


        activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);

                                                                       //   通过反射构造出Activity对象


        activity.attach();// 调用Activity的attach() 方法, 此方法比较重要,主要创建Activity中的Window及


                               // WindowManager  , 等会儿具体分析

       

         以下会逐渐调用Activity中生命周期的方法


        mInstrumentation.callActivityOnCreate(activity, r.state); // 调用Activity中的onCreate方法


       activity.performStart() ;  // 调用

       mInstrumentation.callActivityOnRestoreInstanceState(activity,r.state);

       mInstrumentation.callActivityOnPostCreate(activity,r.state);

       mActivitys.put(r.token,r);  // 压入栈


       }


--------------handleResumeActivity:  开始调用onResume() 方法,

--------------performResumeActivity(); // 调用onResume()方法

        performResumeActivity () {

           ....

           r.activity.performResume();  // 调用Activity中的onResume方法

           .....


       }


到此为止,整个Activity已经创建,启动了,但是他还什么都没有显示,因为没有显示在屏幕上,


 handleResumeActivity() {

    --r.window.getDecorView();                                   //开始把DecorView添加进Window
    --wm.addView(decor, l);


 }

(11)消息循环:Looper.loop(); @ //  frameworks/base/core/java/android/os/Looper.java的loop()函数

    public static final void loop() {

......

    msg.target.dispatchMessage(msg);  //对应frameworks/base/core/java/android/os/handler.java的dispatchMessage

......

}

dispatchMessage调用ActivityThread 里面重载的handleMessage函数.


---------------------------------------->zygote小结----------------------------------------------------------------------------

1. zygote 本身是一个Native的应用程序,与驱动,内核无关,由init进程根据init.rc的配置项创建起来的。


2. zygote 是创建java世界的盘古,创建java世界的步骤:

    (1) 创建AppRuntime对象,并调用它的start。此后的活动由AppRuntime控制。

    (2) 调用startVm创建Java虚拟机,然后调用startReg来注册JNI函数。

    (3) 通过JNI调用com.android.internal.os.ZygoteInit类的main函数,进入Java世界。

    (4) 调用registerZygoteSocket建立socket作为IPC通信服务端,通过这个函数,zygote可以响应子孙后代的请求。同时,zygote通过调用preloadClasses和preloadResouces来预加载类和资源。

    (5) 通过startSystemServer创建一个进程system_server来为Java世界服务。该进程是framework的核心,Java世界中系统的Services都驻留在该进程。

    (6) zygote调用runSelectLoopMode函数进入循环,这个函数使用到了(4)中的socket。这个函数主要用于处理客户连接和客户请求。其中客户在zygote中用ZygoteConnection对象来表示,客户的请求由ZygoteConnection的runOnce来处理。


3. SystemServer(system_server)诞生过程:

    (1) ZygoteInit调用startSystemServer创建system_server进程。

    (2) system_server调用handleSystemProcess完成自己的使命。

    (3) handleSystemProcess抛出异常,最终调用com.android.SystemServer的main函数。

    (4) main函数加载libandroid_server.so,并调用native的init1函数。

    (5) init1函数通过JNI调用com.android.SystemServer的init2函数,init2函数创建一个线程,用于加载各种Services。

    (6) init1函数最终使进程的主线程加入Binder通信系统中。


4. zygote分裂繁殖例子

    ActivityManagerService由SystemServer创建, 并驻留在SystemServer进程中。使用startActivity来启动新的Activity,该Activity附属于一个还未启动的进程,该进程启动过程:

    (1) ActivityManagerService向zygote发送请求消息。

    (2) 每当有请求数据发来时,zygote的runSelectLoopMode函数中就就会调用ZygoteConnection的runOnce函数中fork创建子进程。

    (3) 子进程调用android.app.ActivityThread的main函数。 android.app.ActivityThread实际上是Android中apk程序所对应的进程,它的main函数就是apk程序的main函数。自此,新的activity运行起来了。



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值