【Android面试题】Android Framework核心面试题——Android app进程是怎么启动的?

Android app进程是怎么启动的?

这道题想考察什么?

app进程的创建和启动流程。

考生应该如何回答

分析app如何被fork出来,然后,讲解app启动过程中的重要细节,我们首先分析app启动的方案,然后再重点讲解相关的启动流程。

什么是冷启动和热启动
  1. 冷启动
    当启动应用时,后台没有该应用的进程,这时系统会重新创建一个新的进程分配给该应用,这个启动方式就是冷启动,也就是先实例化Application。
  2. 热启动
    当启动应用时,后台已有该应用的进程(例:按back键、home键,应用虽然会退出,但是该应用的进程是依然会保留在后台,可进入任务列表查看),所以在已有进程的情况下,这种启动会从已有的进程中来启动应用,也就是直接从进程中启动,不需要重新创建Application,这个方式叫热启动。

由于热启动是从已有的后台进程中启动,所以热启动并不会走Application这步,它一般是直接走MainActivity,所以热启动过程只需要创建和初始化一个MainActivity即可,不必创建和初始化Application。

冷启动的启动流程分析

1)启动APP进程

当我们点击Launcher桌面程序的APP图标时,Launcher程序会调用startActivity()函数,通过Binder跨进程通信,发送消息给system_server进程中的AMS。在system_server进程中,由AMS通过socket通信告知Zygote进程fork出一个子进程(APP进程)。

对上面流程中需要进行几点说明:
1) AMS不是一个独立的进程,它只是system_server进程的一个服务;
2)Launcher进程要启动另外一个app就必须发消息给AMS,由AMS发送App进程创建的命令;
3)Launcher是通过去ServiceManager进程中获取AMS的Binder的方案得到AMS的Binder,然后通过这个Binder调用AMS的服务;
4)当AMS收到Launcher启动进程的事件后,会在AMS体系中进行各种检测和判断,最终发现被启动的App进程还未创建;
5)此时AMS会给Zygote发送一个 socket消息,而zygote中的socket服务器会接收到这个消息,然后会执行Zygote 的fork,并产生一个子进程,这个子进程就是APP进程。

具体流程如下图所示:

在这里插入图片描述

1)launcher进程不能直接去启动app进程,所以它会调用SM拿到ATMS的代理对象ActivityTaskManagerProxy,然后执行ActivityTaskManagerProxy的startActivity方法。

2)ActivityTaskManager收到执行startActivity方法的请求后会执行将请求转交给AMS,然后AMS会去判断当前Activity所对于的Application进程是否存在,如果进程存在,那么就是热启动,如果进程不存在那么就是冷启动。在冷启动的时候,AMS将发送socket请求给到Zygote进程,通知zygote去创建app进程。

3)Zygote进程收到socket请求就会去执行fork函数,fork会产生一个子进程,这个进程就是需要启动的app进程了。这个子进程同时就具备了Zygote进程的一切,这个 说明在zygote相关的内容中有详细介绍。

4)开启APP主线程

APP进程启动后,会实例化一个ActivityThread,并在native层面通过反射执行其main函数,同时触发执行attach函数,同时会创建ApplicationThread、Looper、Handler对象,开启主线程消息循环Looper.loop()。

对于上面流程的需要进行几点说明:

1)App进程创建后,Zygote会执行反射相关的代码,通过反射执行ActivityThread的main函数,此时代码进入ActivityThread类,并完成了ActivityThread的初始化。

2)ActivityThread执行main函数的代码如下所示:

public static void main(String[] args) {
	
	...
	//核心代码1
	Looper.prepareMainLooper();

	...
	
	//核心代码2
	ActivityThread thread = new ActivityThread();
	thread.attach(false, startSeq);

	...
	//核心代码3
	Looper.loop();

	...
}

首先,创建了主线程的Looper,并且开启了主线程的Looper.loop(),对线程开始执行消息循环。这样的设计可以让android所有的主线程的事务都封装成为Message,然后通过MessageQueue的循环来完成消息轮询和执行。

其次,核心代码2中创建了ActivityThread对象,同时调用了thread.attach()函数,这个函数会获取AMS服务的binder,然后调用AMS的attachApplication()方法,这个方法会将App的 IApplicationThread 对象传递给AMS,AMS这时候就持有了App的Binder对象,当AMS需要向App进行通信的时候就能够非常的便利了。

5)创建并初始化Application和Activity

ActivityThread的main函数通过调用attach方法进行 Binder 通信,通知system_server进程执行AMS的attachApplication方法。在attachApplication方法中,AMS分别通过bindApplication、scheduleLaunchActivity方法,并且将这些操作封装成Message并通知APP进程的主线程Handler,对APP进程的Application和Activity进行初始化,并执行Application、Activity的生命周期。最后在Activity的生命周期中执行UI的创建和显示。

至此,应用启动流程完成,这里对源码细节不做过多分析。

最后

我整理了一套Android面试题合集,除了以上面试题,还包含【Java 基础、集合、多线程、虚拟机、反射、泛型、并发编程、Android四大组件、异步任务和消息机制、UI绘制、性能调优、SDN、第三方框架、设计模式、Kotlin、计算机网络、系统启动流程、Dart、Flutter、算法和数据结构、NDK、H.264、H.265.音频编解码、FFmpeg、OpenMax、OpenCV、OpenGL ES
在这里插入图片描述

有需要的朋友可以扫描下方二维码,免费领取全部面试题+答案解析!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值