Android高级开发实战:UI、NDK与安全
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

1.2 Android程序的执行流程

1.2.1 Android系统启动过程

Android基于Linux内核系统,启动时最先通过加载器bootloader加载Linux内核,然后初始化Linux内核,最后去调用初始化的init进程。Android从Linux系统启动时一共经过了4个必需的步骤:

(1)init进程(即初始化进程)启动。

(2)Native服务(即本地服务)启动。

(3)System Server(即系统服务)和Android服务启动。

(4)Home启动。

总体的启动过程框架图如下图所示。

1.第一步启动:init进程启动

init是一个由内核启动的并且会对各种设备进行初始化操作的用户级别的进程。内核会自动启动,内核启动之后会通过启动一个用户级程序init的方式,完成引导进程(其实大多数系统的init进程启动都是这样)。init进程是所有其他进程启动的源头,其下会衍生出“受精卵”Zygote、媒体服务media等进程,如下图所示。

当系统启动完成后,init进程将会作为守护进程监视其他进程,如果某个进程被监视到已经结束,init进程就会释放这个结束的进程所占用的系统资源。

init进程的运行流程如下图所示。

2.第二步启动:“受精卵”Zygote进程启动

Zygote进程的作用是每当要执行Java应用程序时,Zygote进程就会派生出执行Java应用的虚拟机的子进程,原因是Android的应用程序是使用Java语言写成的,这些Java程序只能运行在Google自己设计的Dalvik虚拟机之上,而不是以本地进程的形式直接运行在Linux上。每个应用程序都运行在自己独立的Dalvik虚拟机里。

Zygote启动之后才会建立起真正的Android运行空间,初始化建立的Service都是本地服务(Navtive Service)。从Android源码/system/bin/app_process中的main()函数(读者可以在frameworks/base/cmds/app_process/app_main.cpp中找到main函数)中可以看出,app_process进程最先生成一个AppRuntime实例对象,然后开始分析main函数传递过来的参数,并且会将这些参数传递给AppRuntime对象。紧接着生成并且初始化Android虚拟机Dalvik,虚拟机参数完毕之后就开始执行ZygoteInit类的main函数。流程如下图所示。

经过这几个步骤,Zygote就建立好了。

3.第三步启动:系统服务System Server启动

具体流程图如下图所示。

System Server是Android系统一个非常重要的核心进程,从上图可以看出,System Server是由Zygote进程创建而来的。startSystemServer()函数在Zygote上“fork”了一个进程,于是SystemServer就建立了。Android的所有服务循环框架都是建立系统服务SystemServer上的。

4.第四步启动:Home启动

当所有的Java系统服务加载启动完成之后,ActivityManager Service就会运行启动Home的应用。

系统在启动完所有的Android服务后,做了这样一些动作:

(1)使用systemReady()函数通知各个服务,系统已经就绪。

(2)对于ActivityManagerService.systemReady(回调),Home就是在ActivityManagerService. systemReady()通知的过程中建立起来的。

至此Android系统的启动就完成了。

1.2.2 Android应用程序启动过程

经过前面对Android项目目录结构的介绍,以及相关文件的讲解,我们对许多细节已经有所了解,那么Android程序是如何执行的呢?下面做一个总结。

程序发布程序到手机上之后,当双击“抽屉”里该应用程序的图标时,系统会将这个单击事件包装成一个Intent,该Intent包含两个参数:

{action :"android.intent.action.MAIN",
category :"android.intent.category.LAUNCHER" }

这个意图被传递给应用程序之后,在应用程序的功能清单文件中寻找与该意图匹配的意图过滤器,如果匹配成功,则找到相匹配的意图过滤器所在的Activity元素,再根据<activity>元素的“name”属性来寻找其对应的Activity类。接着Android操作系统创建该Activity类的实例对象,对象创建完成之后,会执行该类的onCreate方法,此OnCreate方法是重写其父类Activity的OnCreate方法而实现的。onCreate方法用来初始化Activity实例对象。以下是HelloWorld.java类中onCreate方法的代码:

@Override
    public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
}

其中,super.onCreate(savedInstanceState)的作用是调用其父类Activity的OnCreate方法来实现对界面的画图绘制工作。在实现自定义的Activity子类的OnCreate方法时,一定要记得调用该方法,以确保能够绘制界面。

setContentView(R.layout.main)的作用是加载一个界面。该方法中传入的参数是“R.layout.main”,其含义为R.java类中静态内部类layout的静态常量main的值,而该值是一个指向“res”目录下的“layout”子目录下main.xml文件的标识符。因此代表显示main.xml所定义的画面。

Android程序执行的整个序列图如下图所示。