码迷,mamicode.com
首页 > 移动开发 > 详细

Android启动过程——init,Zygote,SystemServer

时间:2017-06-02 14:57:17      阅读:348      评论:0      收藏:0      [点我收藏+]

标签:接下来   monitor   handler   sof   mem   vector   library   设置   strcmp   

一、Android设备启动经历的三个阶段:Boot Loader;Linux Kernel。Android系统服务;每一个阶段都有自己的启动画面。


1、Android中第一个被启动的进程——init,init进程的PID为1,其它的服务都由其进行创建。它是通过解析init.rc脚本来构建出系统的初始执行状态的。init进程是在系统启动启动过程中启动的。
2、init.rc语法规则:
1)Actions动作
    一个Action实际上就是对应某个事件的过程。

以下给出boot事件的脚本

/* \system\core\rootdir\init.rc*/
    on boot
    # basic network init
    ifup lo
    hostname localhost
    domainname localdomain
 
    # set RLIMIT_NICE to allow priorities from 19 to -20
    setrlimit 13 40 40
 
    # Memory management.  Basic kernel parameters, and allow the high
    # level system server to be able to adjust the kernel OOM driver
    # parameters to match how it is managing things.
    write /proc/sys/vm/overcommit_memory 1
    write /proc/sys/vm/min_free_order_shift 4
    chown root system /sys/module/lowmemorykiller/parameters/adj
    chmod 0220 /sys/module/lowmemorykiller/parameters/adj
    chown root system /sys/module/lowmemorykiller/parameters/minfree
    chmod 0220 /sys/module/lowmemorykiller/parameters/minfree
    ....

语法规则:
on  <trigger>        #触发条件
      <command>   #运行命令
      <command>   #运行命令
       ........
    当<trigger>所描写叙述的触发事件产生时,便会依次运行各种command

Commands命令:
ifup <interface>           使用网络接口<interface>成功连接
hostname <name>       设置主机名为<name>
domainname <name>  设置域名
start <service>             假设该服务为执行的话,启动该服务
stop <service>             假设该服务正在执行的话,停止该服务
............. 

2)Services服务
    Services是可执行程序,它们在特定选项的约束下会被init程序执行或者重新启动。
先看个实例,以下是启动ServiceManager的脚本:

/* \system\core\rootdir\init.rc*/
//组件     进程名            程序文件
service servicemanager /system/bin/servicemanager //service 表明SM是以服务的形式启动的
    class core
    user system                //表明进程是以系统用户system身份执行的
    group system            
    critical                  /* 表明SM是系统中的一个关键服务,
                               * 在系统执行过程中。关键服务是不同意退出的;一旦退出,就会被系统重新启动;
                               * 而假设一个关键服务在4分钟内退出次数大于4。则系统会重新启动*/
    onrestart restart healthd /* 表明一旦SM被重新启动,这些进程zygote等也会被重新启动*/
    onrestart restart zygote
    onrestart restart media
    onrestart restart surfaceflinger
    onrestart restart drm


语法规则:
service  <name>  <pathname>  [<argument>]*
            <option>
            <option>
            .........
name         ---   Service服务名称
pathname   ---  service服务所在的文件路径
argument   ---  启动Service的參数
option        ---  约束选项

options(约束选项)
class <name>             为该Service指定一个class名。同一个class的全部服务必须同一时候启动或者停止;默认情况下全部Service的class均为"default"
user  <username>      再启动服务前将用户切换至<username>,默认情况下用户都是root
group <groupname> [<groupname>]*  再启动服务前将用户组切换至<groupname>
critical                       表明这是对设备至关重要的一个服务。假设它在四分钟内退出超过四次,则设备将重新启动进入恢复模式
disabled                    此服务不会自己主动启动,而是须要通过显示调用服务名来启动
oneshot                     在此服务退出时,不要主动去重新启动它
onrestart                   当此服务重新启动时,运行这些命令


二、系统关键服务
1、Zygote服务
    Zygote依旧是Android系统的核心,zygote是受精卵的意思,能够觉得是Android framework大家族的祖先!

Android中大多数应用进程和系统进程都是通过Zygote来生成的。

    zygote本身是一个应用层的程序,和驱动,内核模块之类的没点关系。

zygote的启动由linux的祖先init启动。zygote其最初的名字是app_process,通过直接调用pctrl把名字给改成了”zygote”

    来看一下Zygote进程在脚本中是被怎样启动的:

    /* \system\core\rootdir\init.zygote64.rc */
    service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
    class main
    socket zygote stream 660 root system
    onrestart write /sys/android_power/request_state wake
    onrestart write /sys/power/state on
    onrestart restart media
    onrestart restart netd
   能够看到Zygote的class是main(ManagerService的class是core)。其路径在/system/bin/app_process64(类似的还有32,32_64,64_32情况);后面跟的都是Zygote的參数。


0)Zygote总的启动过程

技术分享


1)Zygote的源代码路径在\frameworks\base\cmds\app_process目录中:
技术分享


2)先来看Android.mk文件:

    LOCAL_PATH:= $(call my-dir)
    include $(CLEAR_VARS)
 
    LOCAL_SRC_FILES:=         app_main.cpp
 
    LOCAL_LDFLAGS := -Wl,--version-script,art/sigchainlib/version-script.txt -Wl,--export-dynamic
 
    LOCAL_SHARED_LIBRARIES :=         libdl         libcutils         libutils         liblog         libbinder         libandroid_runtime
 
    LOCAL_WHOLE_STATIC_LIBRARIES := libsigchain
 
    LOCAL_MODULE:= app_process
    LOCAL_MULTILIB := both
    LOCAL_MODULE_STEM_32 := app_process32
    LOCAL_MODULE_STEM_64 := app_process64
    include $(BUILD_EXECUTABLE)
 
    # Create a symlink from app_process to app_process32 or 64
    # depending on the target configuration.
    include  $(BUILD_SYSTEM)/executable_prefer_symlink.mk
 
    # Build a variant of app_process binary linked with ASan runtime.
    # ARM-only at the moment.
    ifeq ($(TARGET_ARCH),arm)
其涉及的主要文件是app_main.cpp;


3)app_main.cpp:

/** \frameworks\base\cmds\app_process\app_main.cpp **/
int main(int argc, char* const argv[])
{
    ......
    // 注意runtime是AppRuntime对象
    AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
    /** 中间一系列代码用以解析传入參数argv  **/
 
    ++i;
    /*** 这些參数正是在脚本中传入的Arguments**/
    while (i < argc) {
        const char* arg = argv[i++];
        if (strcmp(arg, "--zygote") == 0) {
            zygote = true;
            /* 注意这里对名字进行了改动,原来的名称为app_process,这里更改为zygote
             * @value static const char ZYGOTE_NICE_NAME[] = "zygote";*/
            niceName = ZYGOTE_NICE_NAME;
        } else if (strcmp(arg, "--start-system-server") == 0) {
            startSystemServer = true;
        } else if (strcmp(arg, "--application") == 0) {
            application = true;
        } else if (strncmp(arg, "--nice-name=", 12) == 0) {
            niceName.setTo(arg + 12);
        } else if (strncmp(arg, "--", 2) != 0) {
            className.setTo(arg);
            break;
        } else {
            --i;
            break;
        }
    }
 
    ......
    /** 传进来的參数 --zygote,则zygote值为true **/
    if (zygote) {
    // 以下接下来分析AppRuntime类的start方法时怎样启动
        runtime.start("com.android.internal.os.ZygoteInit", args);
    } elseif (className) {
        runtime.start("com.android.internal.os.RuntimeInit", args);
    } else {
        ....
        return 10;
    }
}


4)AppRuntime#start来看AppRuntime是怎样启动Zygote的:

 /*
 * 这里启动Android Runtime.它实现了启动虚拟机,同一时候通过"className"来调用
 * 该类中的main函数("static void main(String[] args)");
 */
/* \frameworks\base\core\jni\AndroidRuntime.cpp */
void AndroidRuntime::start(const char* className, const Vector<String8>& options)
{
    static const String8 startSystemServer("start-system-server");
    /*
     * ‘startSystemServer == true‘ means runtime is obsolete and not run from
     * init.rc anymore, so we print out the boot start event here.
     */
    for (size_t i = 0; i < options.size(); ++i) {
        if (options[i] == startSystemServer) {
           const int LOG_BOOT_PROGRESS_START = 3000;
           LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START,  ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
        }
    }
 
    // 环境变量设置ANDROID_ROOT为/system
    const char* rootDir = getenv("ANDROID_ROOT");
    if (rootDir == NULL) {
        rootDir = "/system";
        if (!hasDir("/system")) {
            LOG_FATAL("No root directory specified, and /android does not exist.");
            return;
        }
        setenv("ANDROID_ROOT", rootDir, 1);
    }
 
    /*******开启虚拟机 **********/
    JniInvocation jni_invocation;
    jni_invocation.Init(NULL);
    JNIEnv* env;
    if (startVm(&mJavaVM, &env) != 0) {
        return;
    }
    onVmCreated(env);
 
    /*
     * Register android functions.
     */
    if (startReg(env) < 0) {
        ALOGE("Unable to register all android natives\n");
        return;
    }
 
    /*
     * 调用main函数
     * We want to call main() with a String array with arguments in it.
     * At present we have two arguments, the class name and an option string.
     * Create an array to hold them.
     */
    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);
    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);
    }
 
    /*
     * 启动VM虚拟机,并且这个线程也会变成VM的主线程,当VM退出前该线程都不会退出
     */
    char* slashClassName = toSlashClassName(className);
    jclass startClass = env->FindClass(slashClassName);
    if (startClass == NULL) {
        ALOGE("JavaVM unable to locate class ‘%s‘\n", slashClassName);
        /* keep going */
    } else {
        jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
            "([Ljava/lang/String;)V");
        if (startMeth == NULL) {
            ALOGE("JavaVM unable to find main() in ‘%s‘\n", className);
            /* keep going */
        } else {
            env->CallStaticVoidMethod(startClass, startMeth, strArray);
 
#if 0
            if (env->ExceptionCheck())
                threadExitUncaughtException(env);
#endif
        }
    }
    free(slashClassName);
 
    ALOGD("Shutting down VM\n");
    if (mJavaVM->DetachCurrentThread() != JNI_OK)
        ALOGW("Warning: unable to detach main thread\n");
    if (mJavaVM->DestroyJavaVM() != 0)
        ALOGW("Warning: VM did not shut down cleanly\n");
}
 能够看到这里开启了VM虚拟机,使得Zygote进程终于也执行在虚拟机上,进而去预装载各种系统类。启动SystemServer(这是大部分Android系统服务的所在地),而逐步建立起各种SystemServer的执行环境。

    上面代码主要完毕了三件事情:1>调用了startVM来开启VM虚拟机
                                              2>调用startReg来注冊JNI方法
                                              3>调用com.android.inernel.ZygoteInit类的main函数;

三、ZygoteInit:
      一旦脚本中定义了Arguments——“--start-system-server”,ZygoteInit就会调用startSystemServer方法来进入SystemServer。


1、先接着上面来看,进入ZygoteInit#main方法:

/* @path: \frameworks\base\core\java\com\android\internal\os\ZygoteInit.java */
public static void main(String argv[]) {
    try {
        ......
        /*** 创建了一个socket接口,用来和ActivityManagerService(AMS)通讯 **/
        registerZygoteSocket(socketName);
        ......
 
        // zygote的简单初始化
        SamplingProfilerIntegration.writeZygoteSnapshot();
 
        // 启动后的进行一次初始化GC
        gc();
 
        if (startSystemServer) {
        /*** 启动SystemServer组件 ***/
            startSystemServer(abiList, socketName);
        }
 
        /** 进入一个无限循环,在前面创建的socket接口上等待AMS请求创建新的应用程序进程。 **/
        runSelectLoop(abiList);
 
        // 关闭socket接口
        closeServerSocket();
    } catch (MethodAndArgsCaller caller) {
    } catch (RuntimeException ex) {
    ......
    }
}
    上面main函数中主要完毕三项工作的内容:

1> 调用registerZygoteSocket函数创建了一个socket接口,用来和ActivityManagerService通讯;
2> 调用startSystemServer函数来启动SystemServer组件,将系统的关键服务启动起来;
3> 调用runSelectLoopMode函数进入一个无限循环,等待AMS请求创建新的应用程序进程。


2、ZygoteInit#registerZygoteSocket方法:
    该方法用来创建一个Server端的socket。用来等待Activity管理服务AMS请求Zygote进程来创建新的应用程序进程的。

/**
 * @path: \frameworks\base\core\java\com\android\internal\os\ZygoteInit.java
 * 注冊一个Server端的socket来实现zygote命令通信
 */
private static void registerZygoteSocket(String socketName) {
    if (sServerSocket == null) {
        int fileDesc;
        // @value private static final String ANDROID_SOCKET_PREFIX = "ANDROID_SOCKET_";
        final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;
        try {
            // 获得一个名称为fullSocketName的系统环境变量名
            String env = System.getenv(fullSocketName);
            // 将其转化为一个文件描写叙述符,用来描写叙述一个类型为AF_UNIX的socket
            fileDesc = Integer.parseInt(env);
        } catch (RuntimeException ex) {
            .......
        }
 
        try {
        // 通过该文件描写叙述符来创建Server端的socket
            sServerSocket = new LocalServerSocket(createFileDescriptor(fileDesc));
        } catch (IOException ex) {
            ......
        }
    }
}

 上面代码完毕了三件事情:
1>调用System.getenv
2>调用Integer.phraseInt
3>通过该文件描写叙述符来创建一个Server端的Socket(LocalServerSocket对象),等待AMS向Zygote进程发送的创建新应用程序进程的请求。

3、ZygoteInit#startSystemServer来创建System进程来启动SystemServer组件

    /**
     * @path: \frameworks\base\core\java\com\android\internal\os\ZygoteInit.java
     * Prepare the arguments and fork for the system server process.
     */
    private static boolean startSystemServer(String abiList, String socketName)
            throws MethodAndArgsCaller, RuntimeException {
        ......
        /* 保存System进程的相关启动參数 */
        String args[] = {
            "--setuid=1000",
            "--setgid=1000",
            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1032,3001,3002,3003,3006,3007",
            "--capabilities=" + capabilities + "," + capabilities,
            "--runtime-init",
            "--nice-name=system_server",
            "com.android.server.SystemServer",// 这里是SystemServer所在的包的完整名称
        };
        ZygoteConnection.Arguments parsedArgs = null;
 
        int pid;
 
        try {
        // 解析參数值
            parsedArgs = new ZygoteConnection.Arguments(args);
            ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
            ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
 
            /** 通过此函数来生成一个新的进程。用以承载各种系统服务。
             *  该函数终于实现调用底层的fork来产生一个新的进程。
             *  这个子进程就是Android系统的System进程  **/
            pid = Zygote.forkSystemServer(
                    parsedArgs.uid, parsedArgs.gid,
                    parsedArgs.gids,
                    parsedArgs.debugFlags,
                    null,
                    parsedArgs.permittedCapabilities,
                    parsedArgs.effectiveCapabilities);
            // 由前面args參数值能够看出System进程的UID(用户ID)和SID(用户组ID)均设置为1000
        } catch (IllegalArgumentException ex) {
            throw new RuntimeException(ex);
        }
 
        /* pid=0 表示为子进程 */
        if (pid == 0) {
            if (hasSecondZygote(abiList)) {
                waitForSecondaryZygote(socketName);
            }
            /*** 子进程即是SystemServer所在进程,通过调用该函数来实现启动各种系统服务***/
            handleSystemServerProcess(parsedArgs);
        }
 
        return true;
    }
    上面代码中通过调用Zygote.forkSystemServer来创建一个新的子进程(即Android系统中的System进程);进而通过调用函数handleSystemServerProcess来启动System进程。进而启动各种系统服务。


4、ZygoteInit#runSelectLoop:(这里源代码是5.1,不再是runSelectLoopMode)

/** @path \frameworks\base\core\java\com\android\internal\os\ZygoteInit.java*/
private static void runSelectLoop(String abiList) throws MethodAndArgsCaller {
    ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
    ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
    // 创建一个大小为4的Socket文件描写叙述符数组fdArray,表示Zygote进程最多能同一时候处理4个socket连接
    FileDescriptor[] fdArray = new FileDescriptor[4];
 
    // 前面创建的Server端的Socket。该变量是静态成员变量,将其加入到文件描写叙述符列表fds中
    fds.add(sServerSocket.getFileDescriptor());
    peers.add(null);
 
    int loopCount = GC_LOOP_COUNT;
    /** 消息循环处理   **/
    while (true) {
        int index;
        // gc相关
        if (loopCount <= 0) {
            gc();
            loopCount = GC_LOOP_COUNT;
        } else {
            loopCount--;
        }
  
        try {
        // 将fds中的socket转换到fdArray中
            fdArray = fds.toArray(fdArray);
            /** 调用selectReadable来监控fdArray中的Socket有数据可读
             * (有数据可读意味该socket接收到了一个连接或一个请求) */
            index = selectReadable(fdArray);
        } catch (IOException ex) {
            ......
        }
 
        if (index < 0) {
            ......
        } else if (index == 0) {// 说明AMS与Zygote进程建立了新的连接,但此时并未请求创建新进程
        // 这里仅仅是将连接描写叙述符加入到fds数组中
            ZygoteConnection newPeer = acceptCommandPeer(abiList);
            peers.add(newPeer);
            fds.add(newPeer.getFileDescriptor());
        } else { // 说明AMS向Zygote进程发送了一个创建应用程序进程的请求
            boolean done;
            /** 调用runOnce来创建一个新的应用进程*/
            done = peers.get(index).runOnce();
 
            // 处理完请求后。断开连接
            if (done) {
                peers.remove(index);
                fds.remove(index);
            }
        }
    }
}
    这里是个通常模式的消息循环处理模式,通过静态成员函数selectReadable来推断系统保存的socket是否有数据可读。当AMS与Zygote进程通过socket建立连接,而且AMS向Zygote进程发送创建新的应用程序进程的请求时,调用ZygoteConnection.runOnce来创建新的进程。


四、System进程的启动过程

    前面3.3中分析ZygoteInit.startSystemServer中提到。系统调用handleSystemServerProcess方法来启动System进程。


1、ZygoteInit#handleSystemServerProcess:

/** @path: \frameworks\base\core\java\com\android\internal\os\ZygoteInit.java */
private static void handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs)
        throws ZygoteInit.MethodAndArgsCaller {
    /* System进程是由System进程fork来的,因此它就会获得Zygote进程中前面创建的Server端Socket
     * 而实际System今进程中并不须要这个socket。因此将它关闭*/
    closeServerSocket();
 
    // 设置名称
    if (parsedArgs.niceName != null) {
        Process.setArgV0(parsedArgs.niceName);
    }
 
    final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
    if (systemServerClasspath != null) {
        performSystemServerDexOpt(systemServerClasspath);
    }
 
    if (parsedArgs.invokeWith != null) {
        ....
    } else {
        ClassLoader cl = null;
        if (systemServerClasspath != null) {
            cl = new PathClassLoader(systemServerClasspath, ClassLoader.getSystemClassLoader());
            Thread.currentThread().setContextClassLoader(cl);
        }
 
        /** 传递剩余的參数到SystemServer中,进一步启动System进程 */
        RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
    }
}
    上面代码中完毕两件事:

1>调用closeServerSocket来关闭由Zygote进程中复制来的Socket
2>调用RuntimeInit.zygoteInit方法来进一步启动System进程

2、RuntimeInit.zygoteInit():

/** @path: \frameworks\base\core\java\com\android\internal\os\RuntimeInit.java */
public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
        throws ZygoteInit.MethodAndArgsCaller {
    if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");
 
    // 将Sytem.out与err输出到log中
    redirectLogStreams();
    /** 设置System进程的时区和键盘布局等通用信息  */
    commonInit();
    /** 在System进程中创建一个Binder线程池。nativeZygoteInit会进而调用一个native方法来实现 */
    nativeZygoteInit();
    /** 转往运行SystemServer中的main函数*/
    applicationInit(targetSdkVersion, argv, classLoader);
}
 
private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
        throws ZygoteInit.MethodAndArgsCaller {
    // If the application calls System.exit(), terminate the process
    // immediately without running any shutdown hooks.  It is not possible to
    // shutdown an Android application gracefully.  Among other things, the
    // Android runtime shutdown hooks close the Binder driver, which can cause
    // leftover running threads to crash before the process actually exits.
    nativeSetExitWithoutCleanup(true);
 
    // We want to be fairly aggressive about heap utilization, to avoid
    // holding on to a lot of memory that isn‘t needed.
    VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
    VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
 
    final Arguments args;
    try {
        args = new Arguments(argv);
    } catch (IllegalArgumentException ex) {
        Slog.e(TAG, ex.getMessage());
        // let the process exit
        return;
    }
 
    // Remaining arguments are passed to the start class‘s static main
    /** 因为System进程进入到SystemServer类的main函数中时,已经运行过非常多代码了
     *  因此严格意义上,main已经不是System的入口函数;
     *  为了使得main看起来像System进程的入口函数,而使用该函数来巧妙地去调用它*/
    invokeStaticMain(args.startClass, args.startArgs, classLoader);
}
   上面主要完毕三件事情:

1>调用commonInit来设置System进程的时区和键盘布局等通用信息
2>调用nativeZygoteInit在System进程中创建一个Binder线程池,nativeZygoteInit会进而调用一个native方法来实现 
3>调用applicationInit,事实上是调用invokeStaticMain来进入SystemServer中的main函数。



3、SystemServer#main:
    在书中的分析中一般都是讲通过调用main函数。进而调用init1与init2函数;可是这里是基于Android5.1的源代码。SystemServer貌似发生了非常大的变化,不再存在init1与init2函数了。

(一)以下基于依照书上流程。基于Android4.2分析:
1)先来看SystemServer#main函数:

    /** @path \frameworks\base\services\java\com\android\server\SystemServer.java **/
    native public static void init1(String[] args);
   
    public static void main(String[] args) {
        if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
            SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
        }
 
        ......
 
        // Mmmmmm... more memory!
        dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();
 
        // The system server has to run all of the time, so it needs to be
        // as efficient as possible with its memory usage.
        VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
 
        System.loadLibrary("android_servers");
        /** 看到这里调用了一个重要的方法 init1  **/
        init1(args);
    }
    main函数这里调用了重要的init1函数,该函数是个native本地方法。查到其本地实现方法在com_android_server_SystemServer.cpp文件里。


2)com_android_server_SystemServer#android_server_SystemServer_init1:

    /** @path \frameworks\base\services\jni\com_android_server_SystemServer.cpp*/
    extern "C" int system_init();
 
    static void android_server_SystemServer_init1(JNIEnv* env, jobject clazz)
    {
        system_init();
    }
    看到android_server_SystemServer_init1函数不过一个包装函数,进而调用system_init函数来启动一些系统服务。



3)init1函数的主体实现部分:system_init():

/** @path \frameworks\base\cmds\system_server\library\system_init.cpp*/
extern"C" status_t system_init()
{
    /** 前面Binder机制分析中分析 MediaServer的main函数时,其启动过程也是相似此几步流程
     *  http://blog.csdn.net/woliuyunyicai/article/details/46864567   */
    // 获取一个ProcessState实例
    sp<ProcessState> proc(ProcessState::self());
    // 一个ServiceManager实例
    sp<IServiceManager> sm = defaultServiceManager();
 
    /** GrimReaper是一个死亡接收通知。详细代码见下 **/
    sp<GrimReaper> grim = new GrimReaper();
    // 设置SM的死亡接收通知
    sm->asBinder()->linkToDeath(grim, grim.get(), 0);
 
    char propBuf[PROPERTY_VALUE_MAX];
    property_get("system_init.startsurfaceflinger", propBuf, "1");
    if (strcmp(propBuf, "1") == 0) {
        /*** 启动SurfaceFlinger  **/
        SurfaceFlinger::instantiate();
    }
 
    property_get("system_init.startsensorservice", propBuf, "1");
    if (strcmp(propBuf, "1") == 0) {
        // 启动SensorService(传感器服务器)
        SensorService::instantiate();
    }
 
    /** 这里开启Android runtime; 我们之所以须要做前面这些事情是由于,
     *  Android runtime初始化之前须要这些core system services事先已经被启动。
     *  其它一些服务仅须要在他们进程的main入口函数的開始(调用init函数初始化之前)进行启动就可以**/
    AndroidRuntime* runtime = AndroidRuntime::getRuntime();
 
    JNIEnv* env = runtime->getJNIEnv();
    if (env == NULL) {
        return UNKNOWN_ERROR;
    }
    jclass clazz = env->FindClass("com/android/server/SystemServer");
    if (clazz == NULL) {
        return UNKNOWN_ERROR;
    }
    /** 注意这里通过JNI调用SystemServer类中init2函数,进一步进行初始化 */
    jmethodID methodId = env->GetStaticMethodID(clazz, "init2", "()V");
    if (methodId == NULL) {
        return UNKNOWN_ERROR;
    }
    env->CallStaticVoidMethod(clazz, methodId);
 
    /** 开辟Binder线程池 */
    // ProcessState开辟线程池
    ProcessState::self()->startThreadPool();
    // IPCThreadState增加到线程池
    IPCThreadState::self()->joinThreadPool();
 
    return NO_ERROR;
}
 
 
namespace android {
/**
 * This class is used to kill this process when the runtime dies.
 */
class GrimReaper : public IBinder::DeathRecipient {
public:
    GrimReaper() { }
 
    /* 当ServiceManager死亡之后,就会调用binderDied函数
     * System进程通过调用kill函数来杀死自己 */
    virtual void binderDied(const wp<IBinder>& who)
    {
        kill(getpid(), SIGKILL);
    }
};
 
} // namespace android
    上面代码中主要实现的功能是开启一些重要的系统服务如ServiceManager,SurfaceFlinger。SensorService(传感器服务)。这些服务须要在开启Android Runtime之前就已经被启动,因此放在init1函数中;初始化这些服务完毕之后,使用JNI调用SystemServer类中的init2函数。继续进行初始化。

    以下回到SystemServer类中:


4)SystemServer#init2方法:

/** @path: \frameworks\base\services\java\com\android\server\SystemServer.java */  
public static final void init2() {
    /** 这里创建了一个线程,全部工作都托付给该线程进行处理*/
    Thread thr = new ServerThread();
    thr.setName("android.server.ServerThread");
    thr.start();
}

5)SystemServer#ServerThread完毕的工作:

/** @path: \frameworks\base\services\java\com\android\server\SystemServer.java */ 
class ServerThread extends Thread {
    @Override
    public void run() {
    /*** 创建Looper消息循环  **/
        Looper.prepareMainLooper();
        // 设置进程參数
        android.os.Process.setThreadPriority(
                android.os.Process.THREAD_PRIORITY_FOREGROUND);
        BinderInternal.disableBackgroundScheduling(true);
        android.os.Process.setCanSelfBackground(false);
 
        // 检查上次是否尝试shutdown失败
        {
        ......
        }
 
        ......
        /** 创建一个系统内共享的UI Handler,它至少可以被一下组件所使用:
         *  - WindowManagerPolicy
         *  - KeyguardViewManager
         *  - DisplayManagerService **/
        HandlerThread uiHandlerThread = new HandlerThread("UI");
        uiHandlerThread.start();
        Handler uiHandler = new Handler(uiHandlerThread.getLooper());
        uiHandler.post(new Runnable() {
            @Override
            public void run() {
                android.os.Process.setThreadPriority(
                        android.os.Process.THREAD_PRIORITY_FOREGROUND);
                android.os.Process.setCanSelfBackground(false);
            }
        });
 
        /*** 创建一个仅供WindowManager共享的Handler线程 **/
        HandlerThread wmHandlerThread = new HandlerThread("WindowManager");
        wmHandlerThread.start();
        Handler wmHandler = new Handler(wmHandlerThread.getLooper());
        wmHandler.post(new Runnable() {
            @Override
            public void run() {
                android.os.Process.setThreadPriority(
                        android.os.Process.THREAD_PRIORITY_DISPLAY);
                android.os.Process.setCanSelfBackground(false);
            }
        });
 
        // Critical services...
        boolean onlyCore = false;
        try {
            /** 创建Installer实例   **/
            Slog.i(TAG, "Waiting for installd to be ready.");
            installer = new Installer();
            installer.ping();
           
            /*** 使用SM注冊启动一些重要的服务。这里仅挑选了当中几个重要的Service**/
            // Power Manager
            power = new PowerManagerService();
            ServiceManager.addService(Context.POWER_SERVICE, power);
           
            // Activity Manager
            context = ActivityManagerService.main(factoryTest);
 
            // Display Manager
            display = new DisplayManagerService(context, wmHandler, uiHandler);
            ServiceManager.addService(Context.DISPLAY_SERVICE, display, true);
 
            // Telephony Registry
            telephonyRegistry = new TelephonyRegistry(context);
            ServiceManager.addService("telephony.registry", telephonyRegistry);
            AttributeCache.init(context);
 
            // Package Manager
            pm = PackageManagerService.main(context, installer,
                    factoryTest != SystemServer.FACTORY_TEST_OFF, onlyCore);
            ServiceManager.addService(Context.USER_SERVICE, UserManagerService.getInstance());
 
            mContentResolver = context.getContentResolver();
 
            // Content Manager
            contentService = ContentService.main(context, factoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL);
            ActivityManagerService.installSystemProviders();
 
            // Input Manager
            inputManager = new InputManagerService(context, wmHandler);
 
            // Window Manager
            wm = WindowManagerService.main(context, power, display, inputManager,
                    uiHandler, wmHandler,
                    factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL,
                    !firstBoot, onlyCore);
            ServiceManager.addService(Context.WINDOW_SERVICE, wm);
            ServiceManager.addService(Context.INPUT_SERVICE, inputManager);
 
            ActivityManagerService.self().setWindowManager(wm);
 
        } catch (RuntimeException e) {
        }
 
        ......
        /** Looper消息处理 **/
        Looper.loop();
    }
}

    上面线程主要完毕的事情包含有创建Looper消息循环;以及启动一些系统的关键服务,比方ActivityManagerService、ContentService等,并将其注冊到ServiceManager中。

    以下来看这几个重要的服务是怎样启动的;


五、一些重要的系统服务Service:

1、 AMS(ActivityManagerService)Activity管理服务

     调用:ActivityManagerService.main(factoryTest)

其通过调用ActivityManagerService类中的静态方法main来启动的:

/** @path \frameworks\base\services\java\com\android\server\am\ActivityManagerService.java **/  
public final class ActivityManagerService extends ActivityManagerNative
    implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
   
    static ActivityManagerService mSelf;   
 
    public static final Context main(int factoryTest) {
        /** 创建一个AThread线程 */
        AThread thr = new AThread();
        thr.start();
 
        synchronized (thr) {
            while (thr.mService == null) {
                try {
                    thr.wait();
                } catch (InterruptedException e) {
                }
            }
        }
 
        // 将AThread中创建的AMS实例赋值给m,再赋值给AMS静态变量mSelf
        ActivityManagerService m = thr.mService;
        mSelf = m;
       
        /** AMS两个最重要核心——
         *  - ActivityStack:Activity的记录者与管理者,同一时候也为AMS管理系统执行情况提供了基础
         *  - ActivityTask**/
        ActivityThread at = ActivityThread.systemMain();
        mSystemThread = at;
        Context context = at.getSystemContext();
        context.setTheme(android.R.style.Theme_Holo);
        m.mContext = context;
        m.mFactoryTest = factoryTest;
        m.mMainStack = new ActivityStack(m, context, true);
       
        m.mBatteryStatsService.publish(context);
        m.mUsageStatsService.publish(context);
       
        synchronized (thr) {
            thr.mReady = true;
            thr.notifyAll();
        }
 
        /*** 開始执行  ***/
        m.startRunning(null, null, null, null);
       
        return context;
    }
   
    static class AThread extends Thread {
        ActivityManagerService mService;
        boolean mReady = false;
 
        public AThread() {
            super("ActivityManager");
        }
 
        public void run() {
        /** 创建消息Loopr循环 **/
            Looper.prepare();
 
            android.os.Process.setThreadPriority(
                    android.os.Process.THREAD_PRIORITY_FOREGROUND);
            android.os.Process.setCanSelfBackground(false);
 
            /** 在这里创建AMS实例。用以作为系统中的Activity管理服务 **/
            ActivityManagerService m = new ActivityManagerService();
 
            synchronized (this) {
                mService = m;
                notifyAll();
            }
 
            synchronized (this) {
                while (!mReady) {
                    try {
                        wait();
                    } catch (InterruptedException e) {
                    }
                }
            } 
            Looper.loop();
        }
    }
}

    能够看到进入ActivityManagerService.main函数之后,其会首先创建一个AThread线程,来创建AMS实例。用来作为系统中的Activity管理服务Service(注意这里并没有将其注冊到SM中,须要等到PackageManagerService启动后,才进行注冊)。


2、PMS(PackManagerService):Package管理服务:
    调用:pm = PackageManagerService.main(context, installer,

                    factoryTest != SystemServer.FACTORY_TEST_OFF, onlyCore);

    也是通过调用PackageManagerService的main静态方法来实现的:

/** @path \frameworks\base\services\java\com\android\server\am\ActivityManagerService.java **/
public class PackageManagerService extends IPackageManager.Stub {
    public static final IPackageManager main(Context context, Installer installer,
            boolean factoryTest, boolean onlyCore) {
    // 创建PMS实例。并将其注冊到SM中。且服务名称为package
        PackageManagerService m = new PackageManagerService(context, installer, factoryTest, onlyCore);
        ServiceManager.addService("package", m);
        return m;
    }
}

3、ContentService(Content管理服务):

    调用:ContentService.main(context, factoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL);

/** @path \frameworks\base\core\java\android\content\ContentService.java **/  
public final class ContentService extends IContentService.Stub {
    public static ContentService main(Context context, boolean factoryTest) {
        ContentService service = new ContentService(context, factoryTest);
        ServiceManager.addService(ContentResolver.CONTENT_SERVICE_NAME, service);
        return service;
    }
}

4、WindowManagerService(Window管理服务)

调用:

WindowManagerService.main(context, power, display, inputManager,

                    uiHandler, wmHandler,

                    factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL,

                    !firstBoot, onlyCore);

通过main函数进入:

/** @path: \frameworks\base\services\java\com\android\server\wm\WindowManagerService.java **/  
public class WindowManagerService extends IWindowManager.Stub
    implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs,
    DisplayManagerService.WindowManagerFuncs, DisplayManager.DisplayListener {
   
    public static WindowManagerService main(final Context context,
            final PowerManagerService pm, final DisplayManagerService dm,
            final InputManagerService im,
            final Handler uiHandler, final Handler wmHandler,
            final boolean haveInputMethods, final boolean showBootMsgs,
            final boolean onlyCore) {
        final WindowManagerService[] holder = new WindowManagerService[1];
        wmHandler.runWithScissors(new Runnable() {
            @Override
            public void run() {
                holder[0] = new WindowManagerService(context, pm, dm, im,
                        uiHandler, haveInputMethods, showBootMsgs, onlyCore);
            }
        }, 0);
        return holder[0];
    }
}
    当这些系统关键服务Service建立起来,而且注冊到ServiceManager后。其它进行就能够通过SM来获取这些服务的代理对象(这与Binder通信机制相关),然后通过这些代理对象来使用系统提供的基础服务了。


??

Android启动过程——init,Zygote,SystemServer

标签:接下来   monitor   handler   sof   mem   vector   library   设置   strcmp   

原文地址:http://www.cnblogs.com/ljbguanli/p/6932924.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!