转载自 https://juejin.im/post/5b0d0a0cf265da091f105858
本文阐述了用户点击启动图标后,Android 系统是怎么启动你的应用程序,将应用视图显示在移动设备上,Android 系统在背后做了很多操作,本文通过重点介绍将一些重要信息以及他们的顺序来阐述应用的启动过程。
首先说一下 Android 应用程序的两个特点
- 多入口,和只有一个 main 方法的应用程序不同,Android 应用程序有四大组件构成 ( Activity , Service ) ,每个组件都是一个入口,所以说 Android 应用是多入口的应用。
- 每个 Android 应用运行在一个 独立的 linux 进程拥有自己的 dalvik vm,并且分配唯一的的用户 ID。
那么什么时候会启动应用的进程呢,答案就是什么时候用到应用程序就启动,这种 ‘ 懒汉模式 ‘。
当用户或者其他应用程序用到了属于你的应用程序的组件,比如 ( Activity ,Service ) Android 就会为你的应用程序启动一个新的进程(你的应用进程不存在当前 Android 系统中时),启动的应用进程会伴随着整个 Android 系统,直到 Android 杀掉你应用进程(内存不足或者被用户清除)。
每个应用都有独立的进程,默认情况下,每个应用程序都运行在自己的进程,并且启动一个主线程工作。当你的应用程序 需要打开相册功能就会打开系统的相册应用,因为你的应用和相册应用都有自己独立的应用进程,通过启动相册的操作,在一个进程中启动另外一个进程,这适用于其他应用程序里面的每一个组件。
Android 开机过程
Android 开机的过程加载内核和 init 进程 然后 init 进程又会产生很多守护进程 比如 usb 进程 debug 调试进程 ,这些守护进程一般是处理底层硬件接口。
然后 init 进程又会启动一个 zygote 进程 ,zygote 进程他会创建一个原始 dalvik 虚拟机 然后继承系统资源,和 Android 应用程序框架,然后进入监听状态,随时准备复制一份,当系统请求 zygote 就会 fork出一份新的进程,这个进程就有了 dalvik 虚拟机和系统的资源了。
然后 init 进程还会启动系统服务进程 SystemServer,SystemServer 去创建系统服务类比如 ActivityManagerService (AMS)。再去启动 launcher 应用(桌面启动器)。
所以当在桌面点击 启动 logo 就会通过 binder接口 以ipc的形式,通知 ams 会发起一个startactivity 然后通过 packagemanager.resolveIntent 来获取 activity的信息,并且保存起来,下次就拿来用。
然后调用 geturipermissionlocked 判断有没有权限执行这个操作,然后 ams 检查 activity 在哪个应用栈列里面,然后再判断 activity 所在的 应用进程是否存在,如果 ams 检测到 activity 所在进程为空会去 通知 zygnote 去fork 一个进程,执行 activitythread 的 main 方法 实例化 looper 消息队列,调用 looper。loop去循环消息队列。,然后进程和 ams 绑定在一起,下次就不会创建该activty了。
启动应用程序可以分为三个步骤
- 创建一个进程
- 绑定应用程序
- 启动一个 Activity
创建一个进程
ams 会通过 startprocessLocked 方法向 zygote 请求一个新的进程,通过 socket 的方法 向 zygote 传递参数,zygote fork了一份 调用 zygoteInit.main 方法 ,然后实例化 Activitythread 对象 并返回进程的 id。
每一个进程都有一个主线程,主线程的有一个looper实例来处理消息队列里面的,在遍历里面的消息队列时,run 方法 会调用 looper.loop 方法。 activitythread 也会调用 looper.prepareLoop 和looper.loop 来启动消息循环。详细如图:
163aef7f73aef0d3.png
进程绑定应用程序
这一步的作用就是将进程绑定到应用程序上, ams 调用 bindApplicaiton,让线程发送一个 message 给消息队列,最后在 handler 的 handlemessage 方法调用 hanldebindapplicaiton 方法,接着调用 makeApplicaiton ,将应用程序的类加载到内存上。如图:
163aefd430ac7121.png
启动一个 Activity
上面两步为你创建了进程和加载资源类到进程的内存里面,这一步为了 ams 调用 realstartactiivtyLocked 来启动 activity ,然后调用 schedulelauncheractivity 方法 ,让 Activitythread 发送LAUNCH_ACTIVITY 的标识,然后在 handleMessage 方法调用 handlelaunchActivity 和 performLaunchActivity ,通过 newActivity 传入 classloader,classname 和 intent 来创建对应的 activity 最后调用 oncreate 加载视图方法 setcontentview。最后视图显示在手机上。 如图:
image
总结
当你启动一个 activity 的时候 ,你当前的进程通过 binder 接口 以 ipc 的方式 startactivity 请求 AMS , AMS 判断用户有没有权限请求这个actiivty 再根据应用栈来确定新 activity 的 task ,最后请求 zygote 创建 dalvik 虚拟机 以及加载系统资源类 ,来创建新的进程,调用新进程的 activitythread 类的 main 方法 创建 looper 调用 loop 方法来遍历消息队列。然后 zygote 返回新进程 pid 给 AMS 。 AMS 绑定这个进程到应用上,加载类到进程的内存上,最后调用 handlelaunchActivity 和 performlaunchactivity 启动这个 activity。最后执行 activity 的 oncreate 方法加载视图,执行 onstart 方法使视图可见。
网友评论