面试:Activity的启动流程简述

Activity的启动的整体流程:

1. Launcher进程请求AMS

2. AMS发送创建应用进程请求

3. Zygote进程接受请求并孵化应用进程

4. 应用进程启动ActivityThread

5. 应用进程绑定到AMS

6. AMS发送启动Activity的请求

7. ActivityThread的Handler处理启动Activity的请求

面试必备:Android(9.0)Activity启动流程(一) - 掘金

面试必备:Android(9.0)Activity启动流程(二) - 掘金

一、Launcher进程请求AMS

根Activity的启动流程其实就是桌面上点击一个应用图标进入到应用的第一个Activity的流程,其实桌面也可以看成一个程序,即Launcher。当系统开机后,Launcher也随之被启动,然后将已经安装的应用程序图标显示到桌面上,所以当我们点击一个应用图标其实就是相当于点击活动中的一个button,其相应事件就是Launcher进程请求AMS来启动该应用程序。

在这里插入图片描述

 

发现其实Launcher调用的startActivity其实就是Activity中的startActivity。从这里也可以证明Launcher其实也是个Activity。所以在Launcher启动一个app,和我们平时在startActivity基本是一样的。通过跨进程调用获取AMS,AMS引用作为服务端处于SystemServer进程中,与当前Launcher进程作为客户端与服务端不在同一个进程,所以am返回的是IActivityManager.Stub的代理对象,此时如果要实现客户端与服务端进程间的通信,只需要在AMS继承了IActivityManager.Stub类并实现了相应的方法,而通过下面的代码可以发现AMS刚好是继承了IActivityManager.Stub类的,这样Launcher进程作为客户端就拥有了服务端AMS的代理对象,然后就可以调用AMS的方法来实现具体功能了,就这样Launcher的工作就交给AMS实现了。

二、AMS发送创建应用进程请求

通过上面的分析,我们已经知道现在任务已经交给了AMS,入口是AMS的startActivity。

在这里插入图片描述

2.1 AMS将请求任务转移给Process

//获取即将要启动的Activity的所在的应用程序进程

//如果应用进程已经存在

//应用进程还未创建,则通过AMS调用startProcessLocked()向Zygote进程发送请求

//创建应用进程的用户ID --> startProcess()

2.2 Process向Zygote进程发送创建应用进程请求

与Zygote进程建立了Socket连接

这样AMS就完成了向Zygote进程发送创建应用进程的请求的任务。

三、Zygote进程接受请求并孵化应用进程

在这里插入图片描述

 现在Zygote进程接受请求是在main方法,

,就让我们来看看这个main方法

frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

    @UnsupportedAppUsage
    public static void main(String argv[]) {
        ZygoteServer zygoteServer = new ZygoteServer();
        Runnable caller;
        try {
            ...
			//创建名为zygote的Socket
            zygoteServer.createZygoteSocket(socketName);
            ....
			//由于在init.rc中设置了start-system-server参数,因此
			//这里将启动SystemServer,可见SystemServer由Zygote创建的第一个进程
            if (startSystemServer) {
                Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
                if (r != null) {
                    r.run();
                    return;
                }
            }
           
            caller = Zygote.initBlastulaPool();
            if (caller == null) {
                Log.i(TAG, "Accepting command socket connections");
                //等待AMS的请求
                caller = zygoteServer.runSelectLoop(abiList);
            }
        } catch (Throwable ex) {
            Log.e(TAG, "System zygote died with exception", ex);
            throw ex;
        } finally {
            zygoteServer.closeServerSocket();
        }

        // We're in the child process and have exited the select loop. Proceed to execute the
        // command.
        if (caller != null) {
            caller.run();
        }
    }

复制代码

通过main方法,我们可以知道在这个main方法首先要创建一个Server端的Socket,这个name为”zygote”的Socket用来等待ActivityManagerService来请求Zygote来创建新的应用程序进程,在上面AMS请求的分析中我们也知道客户端将根据这个name来与Zygote的Socket建立连接。接下去会启动SystemServer进程,这个进程会启动各种系统服务,比如与Activity启动息息相关的AMS。最后会调用ZygoteServer.runSelectLoop(abiList)来使创建的Socket进入无限循环,等待AMS请求。让我们来看看这个runSelectLoop

//监听Socket连接,充当服务端Socket

//不断处理客户端的AMS的请求,然后交给processOneCommand

可以发现这个方法是死循环表示不停的监听着Socket连接。acceptCommandPeer方法就是监听是否收到了请求,如果收到了请求就交给processOneCommand来实现

//获取应用程序进程的启动参数

//fork当前进程创建一个子进程

//pid为0则代表这个进程为子进程,即新创建的应用程序进程

于是到这里子进程也就是应用进程就被孵化出来了。你以为这样就结束了?其实还早呢!别忘了我们的最终使命是根Activity的启动,而现在只是有了根Activity所需要的应用进程,革命尚未成功,仍需要努力!

四、应用进程启动ActivityThread

在这里插入图片描述

Android面试题通常涉及Android开发的基础知识、架构设计、性能优化、异常处理以及具体的代码实现等方面。下面是一些常见的Android面试题目及其简要解答: ### 1. 详细解释一下Activity和Fragment的区别? **区别**: - **生命周期**:Activity生命周期比Fragment更长,因为Activity从系统启动到关闭整个过程中都在运行;而Fragment是在一个特定的Activity中存在,并随着该Activity的可见性变化而变化其生命周期。 - **资源消耗**:相比于Fragment,Activity承担了更多的责任和功能,这可能导致更高的资源消耗。而Fragment则通过将UI和业务逻辑分离,使得应用能够更有效地管理内存和性能。 - **交互性和界面控制**:Fragment通常用于添加或切换视图组件,便于构建复杂的用户界面结构。它们可以嵌入到Activity中,以提供动态加载数据、分割屏幕内容等高级功能。 ### 2. 解释一下如何创建自定义布局文件(XML)并将其应用于Activity? **步骤**: 1. 打开项目的`res/layout`目录,新建或编辑一个`.xml`文件。 2. 使用XML标签(如`<LinearLayout>`、`<TextView>`等)来构建布局结构。 3. 保存文件,并在相应的`activity_main.xml`或其他布局文件中引用这个自定义布局。 4. 在`Activity`的`setContentView()`方法中设置这个布局作为活动的根布局。 5. 调整布局属性(如宽度、高度、位置等),并通过`findViewById()`找到需要操作的控件。 ### 3. 说明在Android中实现SharedPreferences存储数据的基本流程及注意事项? **基本流程**: 1. 创建SharedPreferences实例,通常使用`getSharedPreferences()`方法获取或创建一个新的实例。 2. 获取Editor对象,通过Editor可以修改SharedPreferences的内容。 3. 添加键值对,使用`putString()`、`putInt()`等方法。 4. 提交更改,调用Editor的`commit()`方法。 **注意事项**: - SharedPreferences仅适用于轻量级数据存储,对于大数据量的存储并不适合。 - 同一时间只允许一个进程读取或写入SharedPreferences,避免并发访问导致的数据一致性问题。 - 小心使用全局变量,尽管它可以简化代码,但可能导致不必要的耦合和难以追踪的问题。 ### 相关问题 - 题目建议: - **如何在Android中使用RxJava/RxAndroid进行异步操作?** - **简述Android中的MVP/MVVM设计模式以及它们之间的差异。** - **在Android中实现网络请求(如GET/POST请求)的基本流程是什么?** 这些面试题涵盖了Android开发中的一些核心技术和设计理念,有助于评估候选人对Android平台的掌握程度。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值