Android应用启动的本质(一)

概述

从framework层认识应用启动的过程,了解应用启动、切换过程背后的实质,本文以Launcher为切入点。

Launcher

Android用户第一个接触到应用之间的切换,就是从Launcher到其它任意的应用程序。Launcher也是一个由多个Activity构成的程序,与其它应用没有本质上的差别。它的特殊之处,在于它是Android系统启动的第一个应用程序,也是所有返回操作(按Home键)的最终页面,同时它也展示已安装的应用。

比Launcher更早启动的应用程序

答案是有,有许多的服务在系统启动过程被启动了。
init进程是Android系统中用户空间的第一个进程,作为第一个进程,它被赋予了很多极其重要的工作职责,比如创建Zygote和属性服务等。应用程序进程以及运行系统的关键服务的SystemServer进程都是由Zygote进程来创建的,我们也将它称为孵化器。

Zygote

应用之间的切换,一个应用转入后台,同时也伴随着一个应用的启动。启动过程调用了大量的系统服务,而这些系统服务都是已经提前启动了,在Zygote初始化方法中启动的。

所以要先讲述一下Zygote的启动流程,以及他启动过程都干了什么操作。

1、Zygote启动流程

init启动zygote时主要是调用app_main.cpp的main函数中的AppRuntime的start来启动zygote进程。
源码文件:frameworks/base/cmds/app_process/app_main.cpp

int main(int argc, char* const argv[])
{
...

    AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
   ...

    if (zygote) {
        runtime.start("com.android.internal.os.ZygoteInit", args, zygote);//1
    } else if (className) {
        runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
    } else {
        fprintf(stderr, "Error: no class name or --zygote supplied.\n");
        app_usage();
        LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
        return 10;
    }
}

注释1处这里调用runtime的start函数来启动zygote进程,并将args传入,这样启动zygote进程后,zygote进程会将SystemServer进程启动。我们知道runtime指的就是AppRuntime,AppRuntime声明也在app_main.cpp中,它继承AndroidRuntime,也就是我们调用start其实是调用AndroidRuntime的start函数:
源码文件:frameworks/base/core/jni/AndroidRuntime.cpp

void AndroidRuntime::start(const char* className, const Vector& options, bool zygote)
{
    ...
    /* start the virtual machine */
    JniInvocation jni_invocation;
    jni_invocation.Init(NULL);
    JNIEnv* env;
    if (startVm(&mJavaVM, &env, zygote) != 0) {//1
        return;
    }
    onVmCreated(env);
    if (startReg(env) < 0) {//2
        ALOGE("Unable to register all android natives\n");
        return;
    }
    jclass stringClass;
    jobjectArray strArray;
    jstring classNameStr;

    stringClass = env->FindClass("java/lang/String");
    assert(stringClass != NULL);
    //创建数组
    strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL);
    assert(strArray != NULL);
    //从app_main的main函数得知className为com.android.internal.os.ZygoteInit
    classNameStr = env->NewStringUTF(className);
    assert(classNameStr != NULL);
    env->SetObjectArrayElement(strArray, 0, classNameStr);

    for (size_t i = 0; i < options.size(); ++i) {
        jstring optionsStr = env->NewStringUTF(options.itemAt(i).string());
        assert(optionsStr != NULL);
        env->SetObjectArrayElement(strArray, i + 1, optionsStr);
    }
    char* slashClassName = toSlashClassName(className);
    jclass startClass = env->FindClass(slashClassName);
    if (startClass == NULL) {
        ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
        /* keep going */
    } else {
    //找到ZygoteInit的main函数
        jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
            "([Ljava/lang/String;)V");//3
        if (startMeth == NULL) {
            ALOGE("JavaVM unable to find main() in '%s'\n", className);
            /* keep going */
        } else {
        //通过JNI调用ZygoteInit的main函数
            env->CallStaticVoidMethod(startClass, startMeth, strArray);//4

#if 0
            if (env->ExceptionCheck())
                threadExitUncaughtException(env);
#endif
        }
    }
  ...
}

注释1处调用startVm函数来创建JavaVm(DVM)
注释2处调用startReg函数用来为DVM注册JNI。
注释3处的代码用来找到ZygoteInit的main函数,其中startClass从app_main的main函数得知为com.android.internal.os.ZygoteInit。
注释4处通过JNI调用ZygoteInit的main函数,因为ZygoteInit的main函数是Java编写的,因此需要通过JNI调用。
ZygoteInit的main函数后,Zygote便进入了Java框架层,在此之前没有任何Java代码被调用,这是第一个执行Java文件。

public static void main(String argv[]) {
      ...
       try {
        ...       
           //注册Zygote用的Socket
           registerZygoteSocket(socketName);//1
          ...
          //预加载类和资源
          preload();//2
          ...
           if (startSystemServer) {
           //启动SystemServer进程
               startSystemServer(abiList, socketName);//3
           }
           Log.i(TAG, "Accepting command socket connections");
           //等待客户端请求
           runSelectLoop(abiList);//4
           closeServerSocket();
       } catch (MethodAndArgsCaller caller) {
           caller.run();
       } catch (RuntimeException ex) {
           Log.e(TAG, "Zygote died with exception", ex);
           closeServerSocket();
           throw ex;
       }
   }

Zygote做了四件特别重要的事情:
注释1处通过registerZygoteSocket函数来创建一个Server端的Socket,这个name为”zygote”的Socket用来等待ActivityManagerService来请求Zygote来创建新的应用程序进程。
这就是应用启动(冷启动)的实质操作,所有的应用启动以及Activity之间的切换都是通过ActivityManagerService来调度的。具体操作,后面细说。
注释2处用来预加载类和资源。
注释3处用来启动SystemServer进程,这样系统的关键服务也会由SystemServer进程启动起来。
注释4处调用runSelectLoop函数来等待客户端请求

2、总结

1.创建AppRuntime并调用其start方法,启动Zygote进程。
2.创建DVM并为DVM注册JNI.
3.通过JNI调用ZygoteInit的main函数进入Zygote的Java框架层。
4.通过registerZygoteSocket函数创建服务端Socket,并通过runSelectLoop函数等待ActivityManagerService的请求来创建新的应用程序进程。
5.启动SystemServer进程。

Zygote通过fork(复制进程)的形式来创建应用程序进程和SystemServer进程,由于Zygote进程在启动时会创建DVM,因此通过fork而创建的应用程序进程和SystemServer进程可以在内部获取一个DVM的实例拷贝。
除了创建新的应用程序进程,我们要注意的是这个SystemServer进程。

SystemServer干了什么?

启动了大量的服务。
源码文件frameworks/base/services/java/com/android/server/SystemServer.java

private void run() {
       ...
           System.loadLibrary("android_servers");//1
       ...
           mSystemServiceManager = new SystemServiceManager(mSystemContext);//2
           LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
       ...    
        try {
           Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartServices");
           startBootstrapServices();//3
           startCoreServices();//4
           startOtherServices();//5
       } catch (Throwable ex) {
           Slog.e("System", "******************************************");
           Slog.e("System", "************ Failure starting system services", ex);
           throw ex;
       } finally {
           Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
       }
       ...
   }

注释2处创建SystemServiceManager,它会对系统的服务进行创建、启动和生命周期管理。
注释3启动系统的各种服务,startBootstrapServices函数中用SystemServiceManager启动了ActivityManagerService、PowerManagerService、PackageManagerService等服务。
在注释4处的函数中则启动了BatteryService、UsageStatsService和WebViewUpdateService。
注释5处的startOtherServices函数中则启动了CameraService、AlarmManagerService、VrManagerService等服务,这些服务的父类为SystemService。
官方把系统服务分为了三种类型,分别是引导服务、核心服务和其他服务,其中其他服务为一些非紧要和一些不需要立即启动的服务。

你可能感兴趣的:(Android应用启动的本质(一))