本部份内容是关于Android进阶的一些知识总结,涉及到的知识点比较杂,不过都 是面试中几乎常问的知识点,也是加分的点。 关于这部份内容,可能须要有一些具体的项目实践。在面试的过程当中,结合具体自 身实践经历,才能更加深刻透彻的描绘出来。java
(年前有不少加我,今天才一一回复,发现不少都失效了,须要的能够从新加一次)
(顺手留下GitHub连接,须要获取相关面试等内容的能够本身去找)
https://github.com/xiangjiana/Android-MS
(VX:mm14525201314)android
① 点击桌面App图标,Launcher进程采用Binder IPC向system_server进程发起startActivity
请求;
② system_server进程接收到请求后,向zygote进程发送建立进程的请求;
③ Zygote进程fork出新的子进程,即App进程;
④ App进程,经过Binder IPC向sytem_server进程发起attachApplication
请求;
⑤ system_server进程在收到请求后,进行一系列准备工做后,再经过binder IPC向 App进程发送scheduleLaunchActivity
请求;
⑥ App进程的binder线程(ApplicationThread
)在收到请求后,经过handler向主线 程发送LAUNCH_ACTIVITY消息;
⑦ 主线程在收到Message后,经过发射机制建立目标Activity,并回调Activity.onCreate()
等方法。
⑧ 到此,App便正式启动,开始进入Activity生命周期,执行完onCreate/onStart/onResume
方法,UI渲染结束后即可以看到App的主界面。
上面的一些列步骤简单介绍了一个APP启动到主页面显示的过程,可能这些流程中 的一些术语看的有些懵,什么是Launcher,什么是zygote,什么是 applicationThread
..... 下面咱们一一介绍。git
zygote意为“受精卵“。Android是基于Linux系统的,而在Linux中,全部的进程都是 由init进程直接或者是间接fork出来的,zygote进程也不例外。github
在Android系统里面,zygote是一个进程的名字。Android是基于Linux System的, 当你的手机开机的时候,Linux的内核加载完成以后就会启动一个叫“init“的进程。在 Linux System里面,全部的进程都是由init进程fork出来的,咱们的zygote进程也不 例外面试
咱们都知道,每个App其实都是浏览器
因此当系统里面的第一个zygote进程运行以后,在这以后再开启App,就至关于开 启一个新的进程。而为了实现资源共用和更快的启动速度,Android系统开启新进 程的方式,是经过fork第一个zygote进程实现的。因此说,除了第一个zygote进 程,其余应用所在的进程都是zygote的子进程,这下你明白为何这个进程叫“受精 卵”了吧?由于就像是一个受精卵同样,它能快速的分裂,而且产生遗传物质同样的 细胞!服务器
SystemServer
也是一个进程,并且是由zygote进程fork出来的。架构
知道了SystemServer
的本质,咱们对它就不算太陌生了,这个进程是Android Framework里面两大很是重要的进程之一——另一个进程就是上面的zygote进 程。app
为何说SystemServer
很是重要呢?由于系统里面重要的服务都是在这个进程里面 开启的,好比 ActivityManagerService
、PackageManagerService
、 WindowManagerService
等等。框架
ActivityManagerService
,简称AMS,服务端对象,负责系统中全部Activity的生命 周期。 ActivityManagerService
进行初始化的时机很明确,就是在SystemServer
进程开启 的时候,就会初始化ActivityManagerService
。
下面介绍下Android系统里面的服务器和客户端的概 念。
其实服务器客户端的概念不只仅存在于Web开发中,在Android的框架设计中,使 用的也是这一种模式。服务器端指的就是全部App共用的系统服务,好比咱们这里 提到的ActivityManagerService
,和前面提到的PackageManagerService
、 WindowManagerService
等等,这些基础的系统服务是被全部的App公用的,当某 个App想实现某个操做的时候,要告诉这些系统服务,好比你想打开一个App,那 么咱们知道了包名和MainActivity
类名以后就能够打开
Intent intent = new Intent(Intent.ACTION_MAIN); intent.addCategory(Intent.CATEGORY_LAUNCHER); ComponentName cn = new ComponentName(packageName, className); intent.setComponent(cn); startActivity(intent);
可是,咱们的App经过调用startActivity()
并不能直接打开另一个App,这个方法会 经过一系列的调用,最后仍是告诉AMS说:“我要打开这个App,我知道他的住址和 名字,你帮我打开吧!”因此是AMS来通知zygote进程来fork一个新进程,来开启我 们的目标App的。这就像是浏览器想要打开一个超连接同样,浏览器把网页地址发 送给服务器,而后仍是服务器把须要的资源文件发送给客户端的。
知道了Android Framework的客户端服务器架构以后,咱们还须要了解一件事情, 那就是咱们的App和AMS
(SystemServer
进程)还有zygote进程分属于三个独立的进 程,他们之间如何通讯呢?
App与AMS
经过Binder进行IPC
通讯,AMS
(SystemServer
进程)与zygote经过 Socket进行IPC
通讯。后面具体介绍。
那么AMS
有什么用呢?在前面咱们知道了,若是想打开一个App的话,须要AMS
去 通知zygote进程,除此以外,其实全部的Activity的开启、暂停、关闭都须要AMS
来控制,因此咱们说,AMS
负责系统中全部Activity的生命周期。 在Android系统中,任何一个Activity的启动都是由AMS
和应用程序进程(主要是 ActivityThread
)相互配合来完成的。AMS
服务统一调度系统中全部进程的 Activity启动,而每一个Activity的启动过程则由其所属的进程具体来完成。
当咱们点击手机桌面上的图标的时候,App就由Launcher开始启动了。可是,你有 没有思考过Launcher究竟是一个什么东西? Launcher本质上也是一个应用程序,和咱们的App同样,也是继承自Activity packages/apps/Launcher2/src/com/android/launcher2/Launcher.java
public final class Launcher extends Activity implements View.OnClickListener, OnLongClickListener, La uncherModel.Callbacks, View.OnTouchListener { }
Launcher实现了点击、长按等回调接口,来接收用户的输入。既然是普通的App, 那么咱们的开发经验在这里就仍然适用,好比,咱们点击图标的时候,是怎么开启 的应用呢?捕捉图标点击事件,而后startActivity()
发送对应的Intent请求呗!是的,Launcher也是这么作的,就是这么easy!
每一个Activity都持有Instrumentation
对象的一个引用,可是整个进程只会存在一个 Instrumentation
对象。 Instrumentation
这个类里面的方法大多数和Application
和 Activity
有关,这个类就是完成对Application
和Activity
初始化和生命周期的工具 类。Instrumentation
这个类很重要,对Activity生命周期方法的调用根本就离不开 他,他能够说是一个大管家。
ActivityThread
,依赖于UI线程。App和AMS
是经过Binder传递信息的,那么 ActivityThread
就是专门与AMS
的外交工做的。
前面咱们已经知道了App的启动以及Activity的显示都须要AMS
的控制,那么咱们便 须要和服务端的沟通,而这个沟通是双向的。
客户端-->服务端
并且因为继承了一样的公共接口类,ActivityManagerProxy
提供了与 ActivityManagerService
同样的函数原型,使用户感受不出Server是运行在本地仍是 远端,从而能够更加方便的调用这些重要的系统服务。
服务端-->客户端
仍是经过Binder通讯,不过是换了另一对,换成了ApplicationThread
和 ApplicationThreadProxy
。
他们也都实现了相同的接口IApplicationThread
private class ApplicationThread extends ApplicationThreadNative { } public abstract class ApplicationThreadNative extends Binder i mplements IApplicationThread{ } class ApplicationThreadProxy implements IApplicationThread { }
好了,前面罗里吧嗦的一大堆,介绍了一堆名词,可能不太清楚,不要紧,下面结 合流程图介绍。
① 先从Launcher的startActivity()
方法,经过Binder通讯,调用ActivityManagerService
的startActivity
方法。
② 一系列折腾,最后调用startProcessLocked()
方法来建立新的进程。
③ 该方法会经过前面讲到的socket通道传递参数给Zygote进程。Zygote孵化自身。 调用ZygoteInit.main()
方法来实例化ActivityThread
对象并最终返回新进程的pid。
④ 调用ActivityThread.main()
方法,ActivityThread
随后依次调用Looper.prepareLoop()
和Looper.loop()
来开启消息循环。
方法调用流程图以下:
更直白的流程解释:
①App发起进程:
当从桌面启动应用,则发起进程即是Launcher所在进程;当从某 App内启动远程进程,则发送进程即是该App所在进程。发起进程先经过binder发送 消息给system_server
进程;
②system_server进程:
调用Process.start()
方法,经过socket向zygote进程发送创 建新进程的请求;
③zygote进程:
在执行ZygoteInit.main()
后便进入runSelectLoop()
循环体内,当有 客户端链接时便会执行ZygoteConnection.runOnce()
方法,再通过层层调用后fork 出新的应用进程;
④新进程:
执行handleChildProc
方法,最后调用ActivityThread.main()
方法。
上面建立进程后,执行ActivityThread.main()
方法,随后调用attach()方法。
将进程和指定的Application
绑定起来。这个是经过上节的ActivityThread
对象中调用 bindApplication()
方法完成的。该方法发送一个BIND_APPLICATION
的消息到消息 队列中, 最终经过handleBindApplication()
方法处理该消息. 而后调用 makeApplication()
方法来加载App的classes到内存中。
方法调用流程图以下:
更直白的流程解释:
(若是看不懂AMS,ATP等名词,后面有解释)
通过前两个步骤以后, 系统已经拥有了该application
的进程。 后面的调用顺序就是 普通的从一个已经存在的进程中启动一个新进程的activity了。
实际调用方法是realStartActivity()
, 它会调用application线程对象中的 scheduleLaunchActivity()
发送一个LAUNCH_ACTIVITY
消息到消息队列中, 经过 handleLaunchActivity()
来处理该消息。在 handleLaunchActivity()
经过 performLaunchActiivty()
方法回调Activity的onCreate()
方法和onStart()
方法,而后通 过handleResumeActivity()
方法,回调Activity的onResume()
方法,最终显示Activity 界面。
更直白的流程解释:
简称:
ATP: ApplicationThreadProxy
AT: ApplicationThread
AMP: ActivityManagerProxy
AMS: ActivityManagerService
图解:
① system_server进程中调用startProcessLocked
方法,该方法最终经过socket方式, 将须要建立新进程的消息告知Zygote进程,并阻塞等待Socket返回新建立进程的pid;
② Zygote进程接收到system_server发送过来的消息, 则经过fork的方法,将zygote 自身进程复制生成新的进程,并将ActivityThread
相关的资源加载到新进程app process,这个进程多是用于承载activity等组件;
③ 在新进程app process向servicemanager
查询system_server进程中binder服务端 AMS, 获取相对应的Client端,也就是AMP. 有了这一对binder c/s对, 那么app process即可以经过binder向跨进程system_server发送请求,即attachApplication()
④system_server
进程接收到相应binder操做后,通过屡次调用,利用ATP向app process
发送binder请求, 即bindApplication. system_server
拥有ATP/AMS, 每个 新建立的进程都会有一个相应的AT/AMP,从而能够跨进程 进行相互通讯. 这即是进 程建立过程的完整生态链。
以上大概介绍了一个APP从启动到主页面显示经历的流程,主要从宏观角度介绍了 其过程,具体可结合源码理解。
(顺手留下GitHub连接,须要获取相关面试等内容的能够本身去找)
https://github.com/xiangjiana/Android-MS
(VX:mm14525201314)
感谢支持~