Android系統(tǒng)啟動(dòng)流程

Tip

本文主要介紹Android系統(tǒng)重啟動(dòng)到Home啟動(dòng)的過(guò)程,下面是本人整理的時(shí)序圖(由于圖片比較大,你們可以保存到本地放大看):


Android系統(tǒng)啟動(dòng)流程.jpg

而下文也將對(duì)照時(shí)序圖的順序進(jìn)行分析笋熬。

Init進(jìn)程的啟動(dòng)

image.png

上圖是Linux系統(tǒng)的啟動(dòng)流程热某,而Android是基于Linux開(kāi)發(fā)的,所以也符合它的啟動(dòng)流程胳螟。我們可以看到Init進(jìn)程是由內(nèi)核系統(tǒng)fock出來(lái)的昔馋。該進(jìn)程的入口文件在
init.cpp#main(/system/core/init/init.cpp)

bool waiting_for_exec = false;
int main(int argc, char** argv) {
    ...
    // 創(chuàng)建一些文件夾,并掛載設(shè)備糖耸,這些是和 Linux 相關(guān)的
    if (is_first_stage) {
        mount();
        mkdir();
    }
    /*解析init.rc配置文件
     *配置文件位于system/core/rootdir/init.rc中
     *在解析配置文件中會(huì)啟動(dòng)zygote進(jìn)程
     */
    init_parse_config_file("/init.rc");
    ...
    while (true) {
        if (!waiting_for_exec) {
            execute_one_command();
            restart_processes();
        }
      ...
    //阻塞 等待事件發(fā)生
    int nr = TEMP_FAILURE_RETRY(epoll_wait(epoll_fd, &ev, 1, timeout));
    }
}

init.cpp的main函數(shù)會(huì)先去解析init.rc配置文件秘遏,我們這里不深入分析,反正解析完配置文件以后嘉竟,我們會(huì)得到一個(gè)帶啟動(dòng)的進(jìn)程列表邦危,然后進(jìn)入死循環(huán)執(zhí)行啟動(dòng)進(jìn)程,那waiting_for_exec是在什么時(shí)候被置為true的呢舍扰?其實(shí)是在service_start()方法中倦蚪,下文會(huì)分析到,現(xiàn)在我們先略過(guò)边苹。
init.cpp#restart_processes

static void restart_processes()
{
    process_needs_restart = 0;
    service_for_each_flags(SVC_RESTARTING,
                           restart_service_if_needed);
}

其中service_for_each_flags的聲明在init.h中,實(shí)現(xiàn)在init_parse.cpp中:

init.h#service_for_each_flags
void service_for_each_flags(unsigned matchflags,void (*func)(struct service *svc));

init_parse.cpp#service_for_each_flags
void service_for_each_flags(unsigned matchflags,void (*func)(struct service *svc))
{
    struct listnode *node;
    struct service *svc;
    list_for_each(node, &service_list) {
        svc = node_to_item(node, struct service, slist);
        if (svc->flags & matchflags) {
            func(svc);
        }
    }
}

檢查service_list中的所有服務(wù)陵且,對(duì)于帶有SVC_RESTARTING標(biāo)志的服務(wù),則都會(huì)調(diào)用其相應(yīng)的restart_service_if_needed个束。

init.cpp#restart_service_if_needed

//如果有必要的話重啟服務(wù)
static void restart_service_if_needed(struct service *svc)
{
    time_t next_start_time = svc->time_started + 5;

    if (next_start_time <= gettime()) {
        svc->flags &= (~SVC_RESTARTING);
        //啟動(dòng)服務(wù)
        service_start(svc, NULL);
        return;
    }

    if ((next_start_time < process_needs_restart) ||
        (process_needs_restart == 0)) {
        process_needs_restart = next_start_time;
    }
}

init.cpp#service_start

void service_start(struct service *svc, const char *dynamic_args)
{
    ...
    //創(chuàng)建一個(gè)新的進(jìn)程
    pid_t pid = fork();
     ...
    //啟動(dòng)上文中新fork出來(lái)的進(jìn)程
    execve(svc->args[0], (char**) arg_ptrs, (char**) ENV);
}

通過(guò)fork和execve我們會(huì)進(jìn)入app_main(zygote)進(jìn)程慕购。

階段總結(jié)

image.png

app_main(zygote)進(jìn)程的啟動(dòng)

該進(jìn)程的入口文件位于
app_main.cpp(/frameworks/base/cmds/app_process/app_main.cpp)

int main(int argc, char* const argv[])
{
     ...
    AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
    
   if (strcmp(arg, "--zygote") == 0) {
            zygote = true;
            niceName = ZYGOTE_NICE_NAME;
        }
    ...
    if (zygote) {
        runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
    } else if (className) {
        runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
    } else {
       ...
    }
}

當(dāng)我們的命令中包含--zygote的時(shí)候,我們就會(huì)調(diào)用到ZygoteInit播急。
AndroidRuntime.cpp#start(D:\Android\FrameworkSource\frameworks\base\core\jni)

     ...
    JniInvocation jni_invocation;
    jni_invocation.Init(NULL);
    JNIEnv* env;
//如果java虛擬機(jī)已經(jīng)被創(chuàng)建并啟動(dòng)則直接返回
    if (startVm(&mJavaVM, &env, zygote) != 0) {
        return;
    }
    onVmCreated(env);

    /*
     * Register android functions.
     */
    if (startReg(env) < 0) {
        ALOGE("Unable to register all android natives\n");
        return;
    }

    ...
    //指明要調(diào)用的類脓钾,這里涉及到j(luò)ni調(diào)用
    jclass startClass = env->FindClass(slashClassName);
    ...
    //得到com.android.internal.os.ZygoteInit 的main方法的id
    jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
            "([Ljava/lang/String;)V");
    ...
    env->CallStaticVoidMethod(startClass, startMeth, strArray);
    ...

通過(guò)上文的JNI調(diào)用我們就進(jìn)入到Java的世界了
ZygoteInit#main(frameworks/base/core/java/com/android/internal/os/ZygoteInit.java)

//由app_main(zygote)進(jìn)程通過(guò)jni的方式調(diào)用
public static void main(String argv[]) {
          ...
          try {
            //注冊(cè)ZygoteSocket
            registerZygoteSocket(socketName);
          ...
          //預(yù)加載類和資源
            preload();
          ...
            if (startSystemServer) {
                //啟動(dòng)SystemServer進(jìn)程,屬于行的進(jìn)程下文會(huì)詳細(xì)分析
                startSystemServer(abiList, socketName);
            }
            runSelectLoop(abiList); //進(jìn)入循環(huán)模式
            closeServerSocket();
          ...
          } catch (MethodAndArgsCaller caller) {
            caller.run();
          }
        
}

registerZygoteSocket

private static void registerZygoteSocket(String socketName) {
    if (sServerSocket == null) {
        int fileDesc;
        final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;
        try {
            String env = System.getenv(fullSocketName);
            fileDesc = Integer.parseInt(env);
        } catch (RuntimeException ex) {
            ...
        }

        try {
            FileDescriptor fd = new FileDescriptor();
            fd.setInt$(fileDesc); //設(shè)置文件描述符
            sServerSocket = new LocalServerSocket(fd); //創(chuàng)建Socket的本地服務(wù)端
        } catch (IOException ex) {
            ...
        }
    }
}

preload

//預(yù)加載位于/system/etc/preloaded-classes文件中的類
    preloadClasses();
    //預(yù)加載資源桩警,包含drawable和color資源
    preloadResources();
    //預(yù)加載OpenGL
    preloadOpenGL();
    //通過(guò)System.loadLibrary()方法,
    //預(yù)加載"android","compiler_rt","jnigraphics"這3個(gè)共享庫(kù)
    preloadSharedLibraries();
    //預(yù)加載 文本連接符資源
    preloadTextResources();
    //僅用于zygote進(jìn)程昌妹,用于內(nèi)存共享的進(jìn)程
    WebViewFactory.prepareWebViewInZygote();

zygote進(jìn)程內(nèi)加載了preload()方法中的所有資源捶枢,當(dāng)需要fork新進(jìn)程時(shí)握截,采用copy on write技術(shù),如下:

image.png

startSystemServer(略過(guò)烂叔,下文會(huì)分析谨胞,屬于主流程)

runSelectLoop

private static void runSelectLoop(String abiList) throws MethodAndArgsCaller {
    ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
    ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
    //sServerSocket是socket通信中的服務(wù)端,即zygote進(jìn)程蒜鸡。保存到fds[0]
    fds.add(sServerSocket.getFileDescriptor());
    peers.add(null);

    while (true) {
        StructPollfd[] pollFds = new StructPollfd[fds.size()];
        for (int i = 0; i < pollFds.length; ++i) {
            pollFds[i] = new StructPollfd();
            pollFds[i].fd = fds.get(i);
            pollFds[i].events = (short) POLLIN;
        }
        try {
             //處理輪詢狀態(tài)胯努,當(dāng)pollFds有事件到來(lái)則往下執(zhí)行,否則阻塞在這里
            Os.poll(pollFds, -1);
        } catch (ErrnoException ex) {
            ...
        }
        
        for (int i = pollFds.length - 1; i >= 0; --i) {
            //采用I/O多路復(fù)用機(jī)制逢防,當(dāng)接收到客戶端發(fā)出連接請(qǐng)求 或者數(shù)據(jù)處理請(qǐng)求到來(lái)叶沛,則往下執(zhí)行;
            // 否則進(jìn)入continue忘朝,跳出本次循環(huán)灰署。
            if ((pollFds[i].revents & POLLIN) == 0) {
                continue;
            }
            if (i == 0) {
                //即fds[0],代表的是sServerSocket局嘁,則意味著有客戶端連接請(qǐng)求溉箕;
                // 則創(chuàng)建ZygoteConnection對(duì)象,并添加到fds。
                ZygoteConnection newPeer = acceptCommandPeer(abiList);
                peers.add(newPeer);
                fds.add(newPeer.getFileDesciptor()); //添加到fds.
            } else {
                //i>0悦昵,則代表通過(guò)socket接收來(lái)自對(duì)端的數(shù)據(jù)肴茄,并執(zhí)行相應(yīng)操作
                boolean done = peers.get(i).runOnce();
                if (done) {
                    peers.remove(i);
                    fds.remove(i); //處理完則從fds中移除該文件描述符
                }
            }
        }
    }
}

Zygote采用高效的I/O多路復(fù)用機(jī)制,保證在沒(méi)有客戶端連接請(qǐng)求或數(shù)據(jù)處理時(shí)休眠但指,否則響應(yīng)客戶端的請(qǐng)求独郎。

runOnce

boolean runOnce() throws ZygoteInit.MethodAndArgsCaller {

    String args[];
    Arguments parsedArgs = null;
    FileDescriptor[] descriptors;

    try {
        //讀取socket客戶端發(fā)送過(guò)來(lái)的參數(shù)列表
        args = readArgumentList();
        descriptors = mSocket.getAncillaryFileDescriptors();
    } catch (IOException ex) {
        ...
        return true;
    }
    ...

    try {
        //將binder客戶端傳遞過(guò)來(lái)的參數(shù),解析成Arguments對(duì)象格式
        parsedArgs = new Arguments(args);
        ...
        pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
                parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
                parsedArgs.niceName, fdsToClose, parsedArgs.instructionSet,
                parsedArgs.appDataDir);
    } catch (Exception e) {
        ...
    }

    try {
        if (pid == 0) {
            //子進(jìn)程執(zhí)行
            IoUtils.closeQuietly(serverPipeFd);
            serverPipeFd = null;
            //進(jìn)入子進(jìn)程流程
            handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);
            return true;
        } else {
            //父進(jìn)程執(zhí)行
            IoUtils.closeQuietly(childPipeFd);
            childPipeFd = null;
            return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);
        }
    } finally {
        IoUtils.closeQuietly(childPipeFd);
        IoUtils.closeQuietly(serverPipeFd);
    }
}

階段總結(jié)

Zygote啟動(dòng)過(guò)程的調(diào)用流程圖


image.png

1.解析init.zygote.rc中的參數(shù)枚赡,創(chuàng)建AppRuntime并調(diào)用AppRuntime.start()方法氓癌;
2.調(diào)用AndroidRuntime的startVM()方法創(chuàng)建虛擬機(jī),再調(diào)用startReg()注冊(cè)JNI函數(shù)贫橙;
3.通過(guò)JNI方式調(diào)用ZygoteInit.main()贪婉,第一次進(jìn)入Java世界;
4.registerZygoteSocket()建立socket通道卢肃,zygote作為通信的服務(wù)端疲迂,用于響應(yīng)客戶端請(qǐng)求;
5.preload()預(yù)加載通用類莫湘、drawable和color資源尤蒿、openGL以及共享庫(kù)以及WebView,用于提高app啟動(dòng)效率幅垮;
6.zygote完畢大部分工作腰池,接下來(lái)再通過(guò)startSystemServer(),fork得力幫手system_server進(jìn)程,也是上層framework的運(yùn)行載體示弓。
7.zygote功成身退讳侨,調(diào)用runSelectLoop(),隨時(shí)待命奏属,當(dāng)接收到請(qǐng)求創(chuàng)建新進(jìn)程請(qǐng)求時(shí)立即喚醒并執(zhí)行相應(yīng)工作跨跨。

最后,介紹給通過(guò)cmd命令囱皿,來(lái)fork新進(jìn)程來(lái)執(zhí)行類中main方法的方式:(啟動(dòng)后進(jìn)入RuntimeInit.main)

app_process [可選參數(shù)] 命令所在路徑 啟動(dòng)的類名 [可選參數(shù)]

SystemServer初始化

由上文可知勇婴,SystemServer由Zygote fork生成的,改進(jìn)程名為system_server,該進(jìn)程承載著framework的核心服務(wù)嘱腥。啟動(dòng)SystemServer起點(diǎn)是調(diào)用startSystemServer()耕渴,下面是system_server的啟動(dòng)流程:

image.png

上圖前4步驟(即顏色為紫色的流程)運(yùn)行在是Zygote進(jìn)程,從第5步(即顏色為藍(lán)色的流程)ZygoteInit.handleSystemServerProcess開(kāi)始是運(yùn)行在新創(chuàng)建的system_server爹橱,這是fork機(jī)制實(shí)現(xiàn)的(fork會(huì)返回2次)萨螺。
startSystemServer
startSystemServer會(huì)進(jìn)入開(kāi)啟SystemServer進(jìn)程階段,下文會(huì)詳細(xì)分析

private static boolean startSystemServer(String abiList, String socketName)
            throws MethodAndArgsCaller, RuntimeException {
        ...
        String args[] = {
            "--setuid=1000",
            "--setgid=1000",
            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1032,3001,3002,3003,3006,3007,3009,3010",
            "--capabilities=" + capabilities + "," + capabilities,
            "--nice-name=system_server",
            "--runtime-args",
            "com.android.server.SystemServer",
        };
          ZygoteConnection.Arguments parsedArgs = null;
    int pid;
    try {
        //用于解析參數(shù)愧驱,生成目標(biāo)格式
        parsedArgs = new ZygoteConnection.Arguments(args);
        ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
        ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);

        // fork子進(jìn)程慰技,該進(jìn)程是system_server進(jìn)程【見(jiàn)小節(jié)2】
        pid = Zygote.forkSystemServer(
                parsedArgs.uid, parsedArgs.gid,
                parsedArgs.gids,
                parsedArgs.debugFlags,
                null,
                parsedArgs.permittedCapabilities,
                parsedArgs.effectiveCapabilities);
    } catch (IllegalArgumentException ex) {
        throw new RuntimeException(ex);
    }
      //進(jìn)入子進(jìn)程system_server
    if (pid == 0) {
        if (hasSecondZygote(abiList)) {
            waitForSecondaryZygote(socketName);
        }
        // 完成system_server進(jìn)程剩余的工作 【見(jiàn)小節(jié)5】
        handleSystemServerProcess(parsedArgs);
    }
    return true;
    }

startSystemServer函數(shù)主要的作用是準(zhǔn)備參數(shù)并fork新進(jìn)程,從上面可以看出system server進(jìn)程參數(shù)信息為uid=1000,gid=1000,進(jìn)程名為sytem_server组砚,從zygote進(jìn)程fork新進(jìn)程后吻商,需要關(guān)閉zygote原有的socket。另外糟红,對(duì)于有兩個(gè)zygote進(jìn)程情況艾帐,需等待第2個(gè)zygote創(chuàng)建完成。

forkSystemServer流程

Zygote.java(frameworks/base/core/java/com/android/internal/os/Zygote.java)#forkSystemServer

public static int forkSystemServer(int uid, int gid, int[] gids, int debugFlags,
            int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
        VM_HOOKS.preFork();
        int pid = nativeForkSystemServer(
                uid, gid, gids, debugFlags, rlimits, permittedCapabilities, effectiveCapabilities);
        // Enable tracing as soon as we enter the system_server.
        if (pid == 0) {
            Trace.setTracingEnabled(true);
        }
        VM_HOOKS.postForkCommon();
        return pid;
    }

nativeForkSystemServer()方法是本地方法在AndroidRuntime.cpp中注冊(cè)的盆偿,調(diào)用com_android_internal_os_Zygote.cpp中的register_com_android_internal_os_Zygote()方法建立native方法的映射關(guān)系柒爸。

nativeForkSystemServer(com_android_internal_os_Zygote.cpp)

static jint com_android_internal_os_Zygote_nativeForkSystemServer(
        JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids,
        jint debug_flags, jobjectArray rlimits, jlong permittedCapabilities,
        jlong effectiveCapabilities) {
  //fork子進(jìn)程
  pid_t pid = ForkAndSpecializeCommon(env, uid, gid, gids,
                                      debug_flags, rlimits,
                                      permittedCapabilities, effectiveCapabilities,
                                      MOUNT_EXTERNAL_DEFAULT, NULL, NULL, true, NULL,
                                      NULL, NULL);
  if (pid > 0) {
      // zygote進(jìn)程,檢測(cè)system_server進(jìn)程是否創(chuàng)建
      gSystemServerPid = pid;
      int status;
      if (waitpid(pid, &status, WNOHANG) == pid) {
          //當(dāng)system_server進(jìn)程死亡后事扭,重啟zygote進(jìn)程
          RuntimeAbort(env);
      }
  }
  return pid;
}

當(dāng)system_server進(jìn)程創(chuàng)建失敗時(shí)捎稚,將會(huì)重啟zygote進(jìn)程。這里需要注意求橄,對(duì)于Android 5.0以上系統(tǒng)今野,有兩個(gè)zygote進(jìn)程,分別是zygote罐农、zygote64兩個(gè)進(jìn)程条霜,system_server的父進(jìn)程,一般來(lái)說(shuō)64位系統(tǒng)其父進(jìn)程是zygote64進(jìn)程涵亏。

1.當(dāng)kill system_server進(jìn)程后宰睡,只重啟zygote64和system_server蒲凶,不重啟zygote;
2.當(dāng)kill zygote64進(jìn)程后,只重啟zygote64和system_server夹厌,也不重啟zygote豹爹;
3.當(dāng)kill zygote進(jìn)程裆悄,則重啟zygote矛纹、zygote64以及system_server。

ForkAndSpecializeCommon

static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray javaGids, jint debug_flags, jobjectArray javaRlimits, jlong permittedCapabilities, jlong effectiveCapabilities, jint mount_external, jstring java_se_info, jstring java_se_name, bool is_system_server, jintArray fdsToClose, jstring instructionSet, jstring dataDir) {
  SetSigChldHandler(); //設(shè)置子進(jìn)程的signal信號(hào)處理函數(shù)
  pid_t pid = fork(); //fork子進(jìn)程
  if (pid == 0) {
    //進(jìn)入子進(jìn)程
    DetachDescriptors(env, fdsToClose); //關(guān)閉并清除文件描述符

    if (!is_system_server) {
        //對(duì)于非system_server子進(jìn)程光稼,則創(chuàng)建進(jìn)程組
        int rc = createProcessGroup(uid, getpid());
    }
    SetGids(env, javaGids); //設(shè)置設(shè)置group
    SetRLimits(env, javaRlimits); //設(shè)置資源limit

    int rc = setresgid(gid, gid, gid);
    rc = setresuid(uid, uid, uid);

    SetCapabilities(env, permittedCapabilities, effectiveCapabilities);
    SetSchedulerPolicy(env); //設(shè)置調(diào)度策略

     //selinux上下文
    rc = selinux_android_setcontext(uid, is_system_server, se_info_c_str, se_name_c_str);

    if (se_info_c_str == NULL && is_system_server) {
      se_name_c_str = "system_server";
    }
    if (se_info_c_str != NULL) {
      SetThreadName(se_name_c_str); //設(shè)置線程名為system_server或南,方便調(diào)試
    }
    UnsetSigChldHandler(); //設(shè)置子進(jìn)程的signal信號(hào)處理函數(shù)為默認(rèn)函數(shù)
    //等價(jià)于調(diào)用zygote.callPostForkChildHooks()
    env->CallStaticVoidMethod(gZygoteClass, gCallPostForkChildHooks, debug_flags,
                              is_system_server ? NULL : instructionSet);
    ...

  } else if (pid > 0) {
    //進(jìn)入父進(jìn)程,即zygote進(jìn)程
  }
  return pid;
}

fork()創(chuàng)建新進(jìn)程艾君,采用copy on write方式采够,這是linux創(chuàng)建進(jìn)程的標(biāo)準(zhǔn)方法,會(huì)有兩次return,對(duì)于pid==0為子進(jìn)程的返回冰垄,對(duì)于pid>0為父進(jìn)程的返回蹬癌。 到此system_server進(jìn)程已完成了創(chuàng)建的所有工作,接下來(lái)開(kāi)始了system_server進(jìn)程的真正工作虹茶。在前面startSystemServer()方法中逝薪,zygote進(jìn)程執(zhí)行完forkSystemServer()后,新創(chuàng)建出來(lái)的system_server進(jìn)程便進(jìn)入handleSystemServerProcess()方法蝴罪。關(guān)于fork()董济,可查看理解Android進(jìn)程創(chuàng)建流程

HandleSystemServerProcess流程

ZygoteInit.java#handleSystemServerProcess

private static void handleSystemServerProcess(
            ZygoteConnection.Arguments parsedArgs)
            throws ZygoteInit.MethodAndArgsCaller {

       ...
//此處systemServerClasspath環(huán)境變量主要有/system/framework/目錄下的services.jar要门,ethernet-service.jar, wifi-service.jar這3個(gè)文件
final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
if (systemServerClasspath != null) {
        //執(zhí)行dex優(yōu)化操作
        performSystemServerDexOpt(systemServerClasspath);
    }
        //之前傳進(jìn)來(lái)的invokeWith為null虏肾,走eles邏輯
        if (parsedArgs.invokeWith != null) {
            String[] args = parsedArgs.remainingArgs;
            if (systemServerClasspath != null) {
                String[] amendedArgs = new String[args.length + 2];
                amendedArgs[0] = "-cp";
                amendedArgs[1] = systemServerClasspath;
                System.arraycopy(parsedArgs.remainingArgs, 0, amendedArgs, 2, parsedArgs.remainingArgs.length);
            }

            WrapperInit.execApplication(parsedArgs.invokeWith,
                    parsedArgs.niceName, parsedArgs.targetSdkVersion,
                    VMRuntime.getCurrentInstructionSet(), null, args);
        } else {
          //通過(guò)類加載器加載指定目錄下的類并調(diào)用 RuntimeInit.zygoteInit
            ClassLoader cl = null;
            if (systemServerClasspath != null) {
                cl = new PathClassLoader(systemServerClasspath, ClassLoader.getSystemClassLoader());
                Thread.currentThread().setContextClassLoader(cl);
            }
            RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
        }
    }

ZygoteInit.java#performSystemServerDexOpt

private static void performSystemServerDexOpt(String classPath) {
    final String[] classPathElements = classPath.split(":");
    //創(chuàng)建一個(gè)與installd的建立socket連接
    final InstallerConnection installer = new InstallerConnection();
    //執(zhí)行ping操作,直到與installd服務(wù)端連通為止
    installer.waitForConnection();
    final String instructionSet = VMRuntime.getRuntime().vmInstructionSet();

    try {
        for (String classPathElement : classPathElements) {
            final int dexoptNeeded = DexFile.getDexOptNeeded(
                    classPathElement, "*", instructionSet, false /* defer */);
            if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
                //以system權(quán)限欢搜,執(zhí)行dex文件優(yōu)化
                installer.dexopt(classPathElement, Process.SYSTEM_UID, false,
                        instructionSet, dexoptNeeded);
            }
        }
    } catch (IOException ioe) {
        throw new RuntimeException("Error starting system_server", ioe);
    } finally {
        installer.disconnect(); //斷開(kāi)與installd的socket連接
    }
}

將classPath字符串中的apk封豪,分別進(jìn)行dex優(yōu)化操作。真正執(zhí)行優(yōu)化工作通過(guò)socket通信將相應(yīng)的命令參數(shù)炒瘟,發(fā)送給installd來(lái)完成吹埠。

zygoteInit流程

RuntimeInit#zygoteInit(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");

        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "RuntimeInit");
        //重定向日志
        redirectLogStreams();
        //通用組件初始化
        commonInit();
    //本地Zygote初始化 native方法
        nativeZygoteInit();
        //android第一個(gè)app應(yīng)用初始化
        applicationInit(targetSdkVersion, argv, classLoader);
    }

RuntimeInit#commonInit

private static final void commonInit() {
    // 設(shè)置默認(rèn)的未捕捉異常處理方法
    Thread.setDefaultUncaughtExceptionHandler(new UncaughtHandler());

    // 設(shè)置市區(qū),中國(guó)時(shí)區(qū)為"Asia/Shanghai"
    TimezoneGetter.setInstance(new TimezoneGetter() {
        @Override
        public String getId() {
            return SystemProperties.get("persist.sys.timezone");
        }
    });
    TimeZone.setDefault(null);

    //重置log配置
    LogManager.getLogManager().reset();
    new AndroidConfig();

    // 設(shè)置默認(rèn)的HTTP User-agent格式,用于 HttpURLConnection唧领。
    String userAgent = getDefaultUserAgent();
    System.setProperty("http.agent", userAgent);

    // 設(shè)置socket的tag藻雌,用于網(wǎng)絡(luò)流量統(tǒng)計(jì)
    NetworkManagementSocketTagger.install();
}

AndroidRuntime.cpp#com_android_internal_os_RuntimeInit_nativeZygoteInit

static void com_android_internal_os_RuntimeInit_nativeZygoteInit(JNIEnv* env, jobject clazz) {
    //此處的gCurRuntime為AppRuntime,是在AndroidRuntime.cpp中定義的
    gCurRuntime->onZygoteInit();
}

[–>app_main.cpp]

irtual void onZygoteInit() {
    sp<ProcessState> proc = ProcessState::self();
    proc->startThreadPool(); //啟動(dòng)新binder線程
}

ProcessState::self()是單例模式斩个,主要工作是調(diào)用open()打開(kāi)/dev/binder驅(qū)動(dòng)設(shè)備胯杭,再利用mmap()映射內(nèi)核的地址空間,將Binder驅(qū)動(dòng)的fd賦值ProcessState對(duì)象中的變量mDriverFD受啥,用于交互操作做个。startThreadPool()是創(chuàng)建一個(gè)新的binder線程鸽心,不斷進(jìn)行talkWithDriver(),在binder系列文章中的注冊(cè)服務(wù)(addService)詳細(xì)這兩個(gè)方法的執(zhí)行原理居暖。

RuntimeInit.java#applicationInit

private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller {
    //true代表應(yīng)用程序退出時(shí)不調(diào)用AppRuntime.onExit()顽频,否則會(huì)在退出前調(diào)用
    nativeSetExitWithoutCleanup(true);

    //設(shè)置虛擬機(jī)的內(nèi)存利用率參數(shù)值為0.75
    VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
    VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);

    final Arguments args;
    try {
        args = new Arguments(argv); //解析參數(shù)
    } catch (IllegalArgumentException ex) {
        return;
    }

    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

    //調(diào)用startClass的static方法 main() 
    invokeStaticMain(args.startClass, args.startArgs, classLoader);
}

RuntimeInit.java#invokeStaticMain

private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller {
    Class<?> cl = Class.forName(className, true, classLoader);
    ...

    Method m;
    try {
        m = cl.getMethod("main", new Class[] { String[].class });
    } catch (NoSuchMethodException ex) {
        ...
    } catch (SecurityException ex) {
        ...
    }

    int modifiers = m.getModifiers();
    if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
        ...
    }

    //通過(guò)拋出異常,回到ZygoteInit.main()太闺。這樣做好處是能清空棧幀糯景,提高棧幀利用率。
    throw new ZygoteInit.MethodAndArgsCaller(m, argv);
}

還記得在zygote進(jìn)程的ZygoteInit.java的以下代碼嗎省骂?

public static void main(String argv[]) {
    try {
        startSystemServer(abiList, socketName);//啟動(dòng)system_server
        ....
    } catch (MethodAndArgsCaller caller) {
        caller.run(); //
    } catch (RuntimeException ex) {
        closeServerSocket();
        throw ex;
    }
}

很明顯當(dāng)我們拋出MethodAndArgsCaller異常時(shí)會(huì)調(diào)用 caller.run()方法蟀淮。

public static class MethodAndArgsCaller extends Exception implements Runnable {

    public void run() {
        try {
            //根據(jù)傳遞過(guò)來(lái)的參數(shù),可知此處通過(guò)反射機(jī)制調(diào)用的是SystemServer.main()方法
            mMethod.invoke(null, new Object[] { mArgs });
        } catch (IllegalAccessException ex) {
            throw new RuntimeException(ex);
        } catch (InvocationTargetException ex) {
            Throwable cause = ex.getCause();
            if (cause instanceof RuntimeException) {
                throw (RuntimeException) cause;
            } else if (cause instanceof Error) {
                throw (Error) cause;
            }
            throw new RuntimeException(ex);
        }
    }
}

代碼比較簡(jiǎn)單钞澳,就是通過(guò)反射調(diào)用SystemServer類的main()方法怠惶。

SystemServer啟動(dòng)(/frameworks/base/services/java/com/android/server/SystemServer.java)

SystemServer#main

 public static void main(String[] args) {
        //創(chuàng)建了一個(gè)SystemServer對(duì)象
        new SystemServer().run();
    }

SystemServer#run

private void run() {
    //當(dāng)系統(tǒng)時(shí)間比1970年更早,就設(shè)置當(dāng)前系統(tǒng)時(shí)間為1970年
    if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
        SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
    }

    //變更虛擬機(jī)的庫(kù)文件轧粟,對(duì)于Android 6.0默認(rèn)采用的是libart.so
    SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());

    if (SamplingProfilerIntegration.isEnabled()) {
        ...
    }

    //清除vm內(nèi)存增長(zhǎng)上限策治,由于啟動(dòng)過(guò)程需要較多的虛擬機(jī)內(nèi)存空間
    VMRuntime.getRuntime().clearGrowthLimit();

    //設(shè)置內(nèi)存的可能有效使用率為0.8
    VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
    // 針對(duì)部分設(shè)備依賴于運(yùn)行時(shí)就產(chǎn)生指紋信息,因此需要在開(kāi)機(jī)完成前已經(jīng)定義
    Build.ensureFingerprintProperty();

    //訪問(wèn)環(huán)境變量前兰吟,需要明確地指定用戶
    Environment.setUserRequired(true);

    //確保當(dāng)前系統(tǒng)進(jìn)程的binder調(diào)用通惫,總是運(yùn)行在前臺(tái)優(yōu)先級(jí)(foreground priority)
    BinderInternal.disableBackgroundScheduling(true);
    android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_FOREGROUND);
    android.os.Process.setCanSelfBackground(false);

    // 主線程looper就在當(dāng)前線程運(yùn)行
    Looper.prepareMainLooper();

    //加載android_servers.so庫(kù),該庫(kù)包含的源碼在frameworks/base/services/目錄下
    System.loadLibrary("android_servers");

    //檢測(cè)上次關(guān)機(jī)過(guò)程是否失敗揽祥,該方法可能不會(huì)返回
    performPendingShutdown();

    //初始化系統(tǒng)上下文 
    createSystemContext();

    //創(chuàng)建系統(tǒng)服務(wù)管理
    mSystemServiceManager = new SystemServiceManager(mSystemContext);
    //將mSystemServiceManager添加到本地服務(wù)的成員sLocalServiceObjects
    LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);


    //啟動(dòng)各種系統(tǒng)服務(wù)
    try {
        startBootstrapServices(); // 啟動(dòng)引導(dǎo)服務(wù)
        startCoreServices();      // 啟動(dòng)核心服務(wù)
        startOtherServices();     // 啟動(dòng)其他服務(wù)
    } catch (Throwable ex) {
        Slog.e("System", "************ Failure starting system services", ex);
        throw ex;
    }

    //用于debug版本讽膏,將log事件不斷循環(huán)地輸出到dropbox(用于分析)
    if (StrictMode.conditionallyEnableDebugLogging()) {
        Slog.i(TAG, "Enabled StrictMode for system server main thread.");
    }
    //一直循環(huán)執(zhí)行
    Looper.loop();
    throw new RuntimeException("Main thread loop unexpectedly exited");
}

LocalServices通過(guò)用靜態(tài)Map變量sLocalServiceObjects,來(lái)保存以服務(wù)類名為key拄丰,以具體服務(wù)對(duì)象為value的Map結(jié)構(gòu)府树。

SystemServer#performPendingShutdown

private void performPendingShutdown() {
    final String shutdownAction = SystemProperties.get(
            ShutdownThread.SHUTDOWN_ACTION_PROPERTY, "");
    if (shutdownAction != null && shutdownAction.length() > 0) {
        boolean reboot = (shutdownAction.charAt(0) == '1');

        final String reason;
        if (shutdownAction.length() > 1) {
            reason = shutdownAction.substring(1, shutdownAction.length());
        } else {
            reason = null;
        }
        // 當(dāng)"sys.shutdown.requested"值不為空,則會(huì)重啟或者關(guān)機(jī)
        ShutdownThread.rebootOrShutdown(null, reboot, reason);
    }
}

SystemServer#createSystemContext

private void createSystemContext() {
    //創(chuàng)建system_server進(jìn)程的上下文信息
    ActivityThread activityThread = ActivityThread.systemMain();
    mSystemContext = activityThread.getSystemContext();
    //設(shè)置主題
    mSystemContext.setTheme(android.R.style.Theme_DeviceDefault_Light_DarkActionBar);
}

理解Application創(chuàng)建過(guò)程已介紹過(guò)createSystemContext()過(guò)程, 該過(guò)程會(huì)創(chuàng)建對(duì)象有ActivityThread料按,Instrumentation, ContextImpl奄侠,LoadedApk,Application载矿。

SystemServer#startBootstrapServices

private void startBootstrapServices() {
    //阻塞等待與installd建立socket通道
    Installer installer = mSystemServiceManager.startService(Installer.class);

    //啟動(dòng)服務(wù)ActivityManagerService
    mActivityManagerService = mSystemServiceManager.startService(
            ActivityManagerService.Lifecycle.class).getService();
    mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
    mActivityManagerService.setInstaller(installer);

    //啟動(dòng)服務(wù)PowerManagerService
    mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);

    //初始化power management
    mActivityManagerService.initPowerManagement();

    //啟動(dòng)服務(wù)LightsService
    mSystemServiceManager.startService(LightsService.class);

    //啟動(dòng)服務(wù)DisplayManagerService
    mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);

    //Phase100: 在初始化package manager之前垄潮,需要默認(rèn)的顯示.
    mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);

    //當(dāng)設(shè)備正在加密時(shí),僅運(yùn)行核心
    String cryptState = SystemProperties.get("vold.decrypt");
    if (ENCRYPTING_STATE.equals(cryptState)) {
        mOnlyCore = true;
    } else if (ENCRYPTED_STATE.equals(cryptState)) {
        mOnlyCore = true;
    }

    //啟動(dòng)服務(wù)PackageManagerService
    mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
            mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
    mFirstBoot = mPackageManagerService.isFirstBoot();
    mPackageManager = mSystemContext.getPackageManager();

    //啟動(dòng)服務(wù)UserManagerService闷盔,新建目錄/data/user/
    ServiceManager.addService(Context.USER_SERVICE, UserManagerService.getInstance());

    AttributeCache.init(mSystemContext);

    //設(shè)置AMS
    mActivityManagerService.setSystemProcess();

    //啟動(dòng)傳感器服務(wù)
    startSensorService();
}

該方法創(chuàng)建的服務(wù)有:ActivityManagerService, PowerManagerService, LightsService, DisplayManagerService弯洗, PackageManagerService, UserManagerService逢勾, sensor服務(wù)牡整。

SystemServer#startCoreServices

private void startCoreServices() {
    //啟動(dòng)服務(wù)BatteryService,用于統(tǒng)計(jì)電池電量溺拱,需要LightService.
    mSystemServiceManager.startService(BatteryService.class);

    //啟動(dòng)服務(wù)UsageStatsService逃贝,用于統(tǒng)計(jì)應(yīng)用使用情況
    mSystemServiceManager.startService(UsageStatsService.class);
    mActivityManagerService.setUsageStatsManager(
            LocalServices.getService(UsageStatsManagerInternal.class));

    mPackageManagerService.getUsageStatsIfNoPackageUsageInfo();

    //啟動(dòng)服務(wù)WebViewUpdateService
    mSystemServiceManager.startService(WebViewUpdateService.class);
}

創(chuàng)建的服務(wù)有:BatteryService谣辞,UsageStatsService,WebViewUpdateService
SystemServer#startOtherServices

private void startOtherServices() {
        ...
        SystemConfig.getInstance();
        mContentResolver = context.getContentResolver(); // resolver
        ...
        mActivityManagerService.installSystemProviders(); //provider
        mSystemServiceManager.startService(AlarmManagerService.class); // alarm
        // watchdog
        watchdog.init(context, mActivityManagerService); 
        inputManager = new InputManagerService(context); // input
        wm = WindowManagerService.main(...); // window
        inputManager.start();  //啟動(dòng)input
        mDisplayManagerService.windowManagerAndInputReady();
        ...
        mSystemServiceManager.startService(MOUNT_SERVICE_CLASS); // mount
        mPackageManagerService.performBootDexOpt();  // dexopt操作
        ActivityManagerNative.getDefault().showBootMessage(...); //顯示啟動(dòng)界面
        ...
        statusBar = new StatusBarManagerService(context, wm); //statusBar
        //dropbox
        ServiceManager.addService(Context.DROPBOX_SERVICE,
                    new DropBoxManagerService(context, new File("/data/system/dropbox")));
         mSystemServiceManager.startService(JobSchedulerService.class); //JobScheduler
         lockSettings.systemReady(); //lockSettings

        //phase480 和phase500
        mSystemServiceManager.startBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY);
        mSystemServiceManager.startBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
        ...
        // 準(zhǔn)備好window, power, package, display服務(wù)
        wm.systemReady();
        mPowerManagerService.systemReady(...);
        mPackageManagerService.systemReady();
        mDisplayManagerService.systemReady(...);
        
        //下文會(huì)詳細(xì)分析
        mActivityManagerService.systemReady(new Runnable() {
            public void run() {
              ...
            }
        });
    }

SystemServer啟動(dòng)各種服務(wù)中最后的一個(gè)環(huán)節(jié)便是AMS.systemReady()沐扳,詳見(jiàn)ActivityManagerService啟動(dòng)過(guò)程.

到此, System_server主線程的啟動(dòng)工作總算完成, 進(jìn)入Looper.loop()狀態(tài),等待其他線程通過(guò)handler發(fā)送消息到主線再處理泥从。

服務(wù)啟動(dòng)階段

關(guān)于服務(wù)啟動(dòng)階段的詳情請(qǐng)參考Android系統(tǒng)啟動(dòng)-SystemServer#服務(wù)啟動(dòng)階段部分
SystemServiceManager的startBootPhase()貫穿system_server進(jìn)程的整個(gè)啟動(dòng)過(guò)程

image.png

其中PHASE_BOOT_COMPLETED=1000,該階段是發(fā)生在Boot完成和home應(yīng)用啟動(dòng)完畢沪摄。系統(tǒng)服務(wù)更傾向于監(jiān)聽(tīng)該階段躯嫉,而不是注冊(cè)廣播ACTION_BOOT_COMPLETED,從而降低系統(tǒng)延遲卓起。

各個(gè)啟動(dòng)階段所在源碼的大致位置

public final class SystemServer {

    private void startBootstrapServices() {
      ...
      //phase100
      mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
      ...
    }

    private void startCoreServices() {
      ...
    }

    private void startOtherServices() {
      ...
      //phase480 && 500
      mSystemServiceManager.startBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY);
      mSystemServiceManager.startBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
      
      ...
      mActivityManagerService.systemReady(new Runnable() {
         public void run() {
             //phase550
             mSystemServiceManager.startBootPhase(
                     SystemService.PHASE_ACTIVITY_MANAGER_READY);
             ...
             //phase600
             mSystemServiceManager.startBootPhase(
                     SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
          }
      }
    }
}

桌面應(yīng)用啟動(dòng)過(guò)程

通過(guò)上文我們知道當(dāng)所有的服務(wù)啟動(dòng)完成以后我們調(diào)用了 mActivityManagerService.systemReady(),下面我們進(jìn)入到其內(nèi)部看看做了哪些操作
ActivityManagerService#systemReady

 public void systemReady(final Runnable goingCallback) {
    synchronized(this) {
            if (mSystemReady) {
                // If we're done calling all the receivers, run the next "boot phase" passed in
                // by the SystemServer
                if (goingCallback != null) {
                    goingCallback.run();
                }
                return;
            }
    }
       ...
      //啟動(dòng)桌面應(yīng)用程序
      startHomeActivityLocked(mCurrentUserId, "systemReady");
       ...
}

ActivityManagerService#startHomeActivityLocked

boolean startHomeActivityLocked(int userId, String reason) {
        ...
        Intent intent = getHomeIntent();
         ...
        mStackSupervisor.startHomeActivity(intent, aInfo, reason);
         ...  
    }

Intent getHomeIntent() {
        //通過(guò)隱式調(diào)用intent
        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
        intent.setComponent(mTopComponent);
        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
            intent.addCategory(Intent.CATEGORY_HOME);
        }
        return intent;
    }

<pre>

這里getHomeIntent加了一個(gè)Intent.CATEGORY_HOME的Category和敬,系統(tǒng)的Launcher這個(gè)Activity正好有這個(gè)android.intent.category.HOME的Category凹炸,這個(gè)文件在/packages/apps/Launcher2/AndroidManifest.xml

<application
        android:name="com.android.launcher2.LauncherApplication"
        android:label="@string/application_name"
        android:icon="@mipmap/ic_launcher_home"
        android:hardwareAccelerated="true"
        android:largeHeap="@bool/config_largeHeap"
        android:supportsRtl="true">
        <activity
            android:name="com.android.launcher2.Launcher"
            android:launchMode="singleTask"
            android:clearTaskOnLaunch="true"
            android:stateNotNeeded="true"
            android:resumeWhilePausing="true"
            android:theme="@style/Theme"
            android:windowSoftInputMode="adjustPan"
            android:screenOrientation="nosensor">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.HOME" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.MONKEY"/>
            </intent-filter>
        </activity>
</application>

所以這里是隱式的啟動(dòng)了Launcher戏阅,接著調(diào)用mStackSupervisor的startHomeActivity方法

ActivityStackSupervisor#startHomeActivity(/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java))

void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason) {
        ...
        startActivityLocked(null /* caller */, intent, null /* resolvedType */, aInfo,
                null /* voiceSession */, null /* voiceInteractor */, null /* resultTo */,
                null /* resultWho */, 0 /* requestCode */, 0 /* callingPid */, 0 /* callingUid */,
                null /* callingPackage */, 0 /* realCallingPid */, 0 /* realCallingUid */,
                0 /* startFlags */, null /* options */, false /* ignoreTargetSecurity */,
                false /* componentSpecified */,
                null /* outActivity */, null /* container */,  null /* inTask */);
       
    }

這里調(diào)用了startActivityLocked方法,其實(shí)這個(gè)方法就是我們平時(shí)調(diào)用startActivity方法之后會(huì)調(diào)用的方法了啤它,至此桌面就被啟動(dòng)起來(lái)了奕筐。

總結(jié)

關(guān)于Android系統(tǒng)從開(kāi)機(jī)到啟動(dòng)桌面大概的過(guò)程如下:

1.啟動(dòng)linux內(nèi)核,fork第一個(gè)進(jìn)程init
2.init進(jìn)程解析init.rc文件变骡,然后fork出眾多進(jìn)程离赫,zygote進(jìn)程是其中之一
3.zygote進(jìn)程啟動(dòng)的虛擬機(jī),從C++環(huán)境切換到Java環(huán)境塌碌,并fork出system_server進(jìn)程
4.SystemServer啟動(dòng)眾多的系統(tǒng)Service如ActivityManagerService,WindowMangerService等
5.ActivityManagerService啟動(dòng)桌面Activity Luncher

參考

Android M系統(tǒng)啟動(dòng)流程
Android系統(tǒng)啟動(dòng)-概述
Android系統(tǒng)啟動(dòng)-Init篇
Android系統(tǒng)啟動(dòng)-zygote篇
Android系統(tǒng)啟動(dòng)-SystemServer上篇
Android系統(tǒng)啟動(dòng)-SystemServer下篇
深入理解init
深入理解 Zygote

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末渊胸,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子台妆,更是在濱河造成了極大的恐慌翎猛,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,324評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件接剩,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)垮刹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門蟋定,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人鹃两,你說(shuō)我怎么就攤上這事遗座。” “怎么了俊扳?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,328評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵途蒋,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我拣度,道長(zhǎng)碎绎,這世上最難降的妖魔是什么螃壤? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,147評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮筋帖,結(jié)果婚禮上奸晴,老公的妹妹穿的比我還像新娘。我一直安慰自己日麸,他們只是感情好寄啼,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,160評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著代箭,像睡著了一般墩划。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上嗡综,一...
    開(kāi)封第一講書(shū)人閱讀 51,115評(píng)論 1 296
  • 那天乙帮,我揣著相機(jī)與錄音,去河邊找鬼极景。 笑死察净,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的盼樟。 我是一名探鬼主播氢卡,決...
    沈念sama閱讀 40,025評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼晨缴!你這毒婦竟也來(lái)了译秦?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,867評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤击碗,失蹤者是張志新(化名)和其女友劉穎筑悴,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體延都,經(jīng)...
    沈念sama閱讀 45,307評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡雷猪,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,528評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了晰房。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片求摇。...
    茶點(diǎn)故事閱讀 39,688評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖殊者,靈堂內(nèi)的尸體忽然破棺而出与境,到底是詐尸還是另有隱情,我是刑警寧澤猖吴,帶...
    沈念sama閱讀 35,409評(píng)論 5 343
  • 正文 年R本政府宣布摔刁,位于F島的核電站,受9級(jí)特大地震影響海蔽,放射性物質(zhì)發(fā)生泄漏共屈。R本人自食惡果不足惜绑谣,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,001評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望拗引。 院中可真熱鬧借宵,春花似錦、人聲如沸矾削。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,657評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)哼凯。三九已至欲间,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間断部,已是汗流浹背猎贴。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,811評(píng)論 1 268
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留家坎,地道東北人嘱能。 一個(gè)月前我還...
    沈念sama閱讀 47,685評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像虱疏,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子苏携,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,573評(píng)論 2 353