首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Android应用启动流程

Android应用启动流程
EN

Stack Overflow用户
提问于 2012-02-04 00:23:39
回答 3查看 10K关注 0票数 6

我正在搜索一些关于如何在android上启动应用程序的信息。我想找出使受精卵和关于fork()的信息。你知道一些有用的网站或书籍吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-04-06 06:28:55

我已经在我的博客上写了一个分为两部分的系列文章来解释Android应用程序的启动过程-

http://multi-core-dump.blogspot.com/2010/04/android-application-launch.html

http://multi-core-dump.blogspot.com/2010/04/android-application-launch-part-2.html

我希望你会发现它是有用的。

票数 17
EN

Stack Overflow用户

发布于 2012-02-04 01:07:15

this演示文稿中有一个很好的解释。它部分是用韩语写的,但大部分信息是用英语写的。

票数 2
EN

Stack Overflow用户

发布于 2019-10-22 21:05:13

这里有一个基于AOSP 9.0.0的简明而精确的答案(过程非常复杂,所以简明的答案仍然不会很短)。

每个Android Java进程都是从Zygote派生的,所以首先是Zygote是如何启动的。

初始化进程是linux中的第一个进程,它启动可执行文件app_process,它的内部是:

代码语言:javascript
运行
复制
(entry point of app_process)int main
    ->void AndroidRuntime::start
        startVm    //start Java VM
        startReg    //register common native functions
        //call java method ZygoteInit.main from native code
        env->CallStaticVoidMethod  

然后是最重要的java方法: ZygoteInit.main,我们从上面的原生代码"env->CallStaticVoidMethod“中获得。

当您在主活动的onCreate中设置断点并开始调试应用程序并在那里中断时,这也是调用堆栈中的第一个方法。但实际上你的应用程序永远不会到达ZygoteInit.main的开始,它只在app_process(或者说Zygote)中从头开始执行。

代码语言:javascript
运行
复制
//Java code
->ZygoteInit.main  
    //Android application never get here(the beginning)
    //start system server process which contains AMS/WMS,etc
    forkSystemServer  

    //for Zygote, runSelectLoop never return
    //for Android application, runSelectLoop returns a Runnable 
    //whose run() method will just execute ActivityThread.main 
    //which is considered as the real main entry of Android application
    //since it contains the message loop
    caller = zygoteServer.runSelectLoop
    ->zygoteServer.runSelectLoop
        //this is the main loop of Zygote who is a 
        //server that receive process-creating requests
        //from client processes and fork them
        loop forever

            //Zygote wait here for other process's requests to start new Java process
            Os.poll(pollFds, -1);

            //after wake up upon requests arrive, process the request
            final Runnable command = connection.processOneCommand(this);
            ->ZygoteConnection.processOneCommand
                 read and parse process-start request command from client process

                 //the native linux fork() is executed in this methdod
                 //after it returns, we can decide which process we are in 
                 //from pid's value just like the native fork()
                 pid = Zygote.forkAndSpecialize

                 //if in child                        
                 return handleChildProc
                 ->ZygoteConnection.handleChildProc
                     return ZygoteInit.zygoteInit
                     ->ZygoteInit.zygoteInit
                         RuntimeInit.commonInit();
                         ZygoteInit.nativeZygoteInit();//JNI method
                             //native code
                             ->AppRuntime::onZygoteInit()
                                 sp<ProcessState> proc = ProcessState::self();
                                 //starting thread pool which contains binder threads
                                 proc->startThreadPool();
                         return RuntimeInit.applicationInit
                         ->RuntimeInit.applicationInit
                             return findStaticMain
                             ->RuntimeInit.findStaticMain
                                 //MethodAndArgsCaller is a Runnable, 
                                 //whose run() is constructed so that 
                                 //it just call ActivityThread.main()
                                 //it is ActivityThread since there is a string parameter 
                                 //whose content is "android.app.ActivityThread" from the client process's request
                                 return new MethodAndArgsCaller
                 //if in parent process i.e. Zygote
                 return null

            //if in forked child process
            return command;
            //if in parent process i.e. Zygote
            continue to run the loop

    //Zygote never get here
    //for Android application, now caller contains a MethodAndArgsCaller which is a Runnable
    //whose run() calls ActivityThread.main and never return
    //since ActivityThread.main runs the main message loop        
    caller.run();

当您启动一个活动时,最后您将进入Activity Manager Service(AMS,它在系统服务器进程中)。如果该活动的流程尚未创建,则AMS会向Zygote服务器发送process-start请求(在上述的zygote流程中,由init进程启动),流程如下:

代码语言:javascript
运行
复制
//in AMS (system server process)
final String entryPoint = "android.app.ActivityThread";
return startProcessLocked(....,entryPoint, ....);
->startProcessLocked        
    ->Process.start
        ->ZygoteProcess.start
            ->ZygoteProcess.startViaZygote
                ->ZygoteProcess.zygoteSendArgsAndGetResult
                    //send the request to Zygote server through sockets
                    //note that "android.app.ActivityThread" is send to Zygote server as a parameter

此时,上面列出的Zygote代码将从

代码语言:javascript
运行
复制
Os.poll(pollFds, -1);

并派生子进程,在此之后,父进程(即Zygote )将再次执行轮询,等待下一个请求,派生的子进程将从runSelectLoop返回并执行ActivityThread.main,如上面的代码清单所示。

因此,新进程的确切入口点将在Zygote.forkAndSpecialize内部的本机fork()之后,确切地说是在名为ForkAndSpecializeCommon的本机函数中,然后一直向上经过一个返回路由,直到

代码语言:javascript
运行
复制
caller = zygoteServer.runSelectLoop

在ZygoteInit.main中。因此,尽管安卓应用程序的调用堆栈从ZygoteInit.main开始,但在ZygoteInit.main中执行的代码是在调用runSelectLoop之后开始的,而不是从ZygoteInit.main的开头开始。

关于Activity:事实上,Activity与入口点或启动过程无关。当AMS随时向进程发送Activity-start请求时,就会启动Activity。因此,当接收到启动请求时,活动启动流程始终在主消息循环中开始,它由来自AMS的消息驱动,并且与应用程序启动流程完全解耦。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9131898

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档