[译]Android系统是如何启动应用程序的?从Zygote到Activity的onCreate()

本文解释了用户点击应用程序图标以后,Android系统是如何启动您的应用程序的。 为了将您的应用程序的启动界面呈现给用户,Android系统在背后作了不少繁重的工做。 本文将经过重点介绍其中的一些重要阶段以及它们之间的顺序来详细阐述应用程序的启动过程。android

Android应用程序有两个特色:浏览器

  1. 拥有多个入口:Android应用程序由不一样的组件组成,它们也能够调用其余应用的组件。这些组件就至关于应用程序的多个入口。所以,它们与具备单一入口的传统应用程序(如main()方法)并不相同。
  2. 拥有本身的小世界:每一个Android应用程序都运行在一个单独的进程中,它有本身的Dalvik VM实例并被分配一个惟一的用户ID。

什么时候启动应用程序的进程?

在任何须要Android应用程序进程的时候启动。app

每当用户或其余系统组件请求执行属于您的应用程序的组件(多是service,activity或intent receiver)时,Android系统都会为您的应用程序启动一个新的进程(若是它还没有运行)。通常来讲,这个进程会一直运行直到它被系统杀死。 应用程序的进程是按需建立的,而且在您看到应用程序的启动界面以前会发生许多事情。框架

每一个应用程序都运行在它本身的进程中:默认状况下,每一个Android应用程序都运行在本身的Android进程中,它是一个Linux进程,而且会启动一个线程。 例如,当您单击电子邮件中的超连接时,网页会在浏览器窗口中打开。 您的邮件客户端和浏览器是两个独立的应用程序,它们运行在两个单独的独立进程中。 click事件会致使Android平台启动一个新进程,以便它能够在本身的进程中实例化浏览器。这一样适用于应用程序中的其余任何组件。socket

Zygote : 孕育新的生命,新的进程

先让咱们快速回顾下Android系统的启动过程。与大多数基于Linux的系统同样,首先引导加载程序会加载内核并启动init进程。而后,init进程产生称为“守护进程”的低级Linux进程,例如android调试守护进程,USB守护进程等。这些守护进程一般都是用于处理底层硬件接口的。oop

接下来init进程会启动一个很是有趣的进程,称为'Zygote'。线程

顾名思义,这是Android应用程序的起点。zygote进程在内部会先初始化一个Dalvik虚拟机的实例,继而加载全部Android应用程序框架和安装在系统上的各类应用程序所使用的经常使用类,最后进入一种监听状态,随时准备被复制。当系统其它模块但愿建立新进程时,它们会向zygote进程发出请求,zygote进程监听到该请求后,会相应地fork出新的进程,因而这个新进程在初生之时,就先天具备了本身的Dalvik虚拟机以及系统资源。3d

zygote进程启动以后,init进程会启动运行时进程(runtime process)。调试

而后zygote进程又启动一个称为系统服务(system server)的管理良好的进程。 系统服务进程会启动系统的全部核心服务,好比activity manager service、hardware services。 此时,系统已准备好启动第一个应用程序 - Home应用程序,该应用程序显示主屏幕,也称为应用程序启动器。cdn

当用户点击启动器中的应用程序图标时...

点击事件被转换成执行startActivity(intent)方法,并经过Binder IPC路由到ActivityManagerService。ActvityManagerService会执行如下几个步骤:

  1. 收集intent的目标Activity的相关信息。这个过程是经过调用PackageManager的resolveIntent()方法完成的。默认使用的是PackageManager.MATCH_DEFAULT_ONLY和PackageManager.GET_SHARED_LIBRARY_FILES参数。
  2. 目标Activity的相关信息会被保存到intent中以免从新执行此步骤。
  3. 调用grantUriPermissionLocked()方法来检查用户是否有足够的权限来调用intent的目标Activity。
  4. 若是用户有足够的权限,ActivityManagerService会检查目标Activity是否须要在新的任务栈中启动。任务栈的建立依赖于Intent的flag参数,好比FLAG_ACTIVITY_NEW_TASK、FLAG_ACTIVITY_CLEAR_TOP等。
  5. 最后检查该应用程序进程的ProcessRecord是否已经存在。若是ProcessRecord为null,ActivityManager会建立一个新的进程来实例化目标Activity。

正如你上面看到的,当用户点击一个图标并启动一个新的应用程序时,背后会发生许多事情。完整的过程以下图所示:

应用程序进程启动过程当中的三个不一样阶段:

  1. Process Creation
  2. Binding Application
  3. Launching Activity / Starting Service / Invoking intent receiver...

Process Creation

ActivityManagerService经过调用startProcessLocked()方法向Zygote请求建立一个新的进程,该方法经过socket链接向Zygote进程发送参数。因而Zygote便复制出一份本身的副本并调用ZygoteInit.main(),而后实例化ActivityThread对象并返回新建立进程的进程ID。

每一个进程都默认有一个线程,即主线程。主线程有一个Looper实例来处理来自消息队列的消息,在遍历这个消息队列的时候,其中的run()方法每次都会调用Looper.loop()。Looper的工做就是从消息队列中取出消息并调用相应的方法来处理它们。ActivityThread随后会调用Looper.prepareLoop()和Looper.loop()来启动消息循环。

下面这个序列图详细描述了这一过程:

Application Binding:

下一步是将这个新建立的进程绑定到指定的应用程序上。首先ActivityManagerService调用bindApplication()方法,进而触发线程对象将BIND_APPLICATION消息发送到消息队列。Handler检索此消息,而后调用handleMessage()方法触发操做handleBindApplication()。该方法会调用makeApplication()方法将应用程序的某些特定的类加载到内存中。

下面这个序列图详细描述了这一过程:

Launching an Activity:

在上一步以后,系统已经建立好了应用程序进程,并将应用程序的类加载到了进程的专属内存中。

Activity的启动过程从realStartActivity()方法开始,首先ActivityManagerService会调用sheduleLaunchActivity()方法,进而触发线程对象将LAUNCH_ACTIVITY消息发送到消息队列。该消息由handleLaunchActivity()方法处理。

假设用户点击的是视频浏览器应用程序的图标,启动Activity的序列图以下所示。

Activity调用onCreate()方法后,便开启了属于它的生命周期。

相关文章
相关标签/搜索