activity启动流程简述

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xutao20170209/article/details/72773185

Activity是Android四大组件中唯一与用户交互的组件,也是最重要,最复杂的组件, 这里以在新进程中启动Activity为例介绍其启动流程.由于Activity启动过程复杂,代码量大,这里就不贴代码了,直接写调用的函数和作用.


发起进程:

Activity.startActivity()
Instrumentation.execStartActivity()
调用标准语句ActivityManagerNative.getDefault().startActivity(args...)进入AMS

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

system_server进程:

ActivityManagerService.startActivity()
ActivityStackSupervisor.startActivityMayWait()
解析intent,并把信息保存在ActivityInfo中。如果有多个activity满足要求,弹出对话框让用户选择。
ActivityStackSupervisor.startActivityLocked()
根据resultTo参数在activity stack里面查找调用者的ActivityRecord,以及创建被启动activity的ActivityRecord。
ActivityStackSupervisor.startActivityUncheckedLocked()
根据启动模式找到或创建activity所属于的任务栈,进行任务栈的相关操作.这里注意一点,如果intent里面的启动模式与AndroidManifest.xml文件里面的启动模式冲突,以AndroidManifest.xml文件为准.
ActivityStack.startActivityLocked()
将目标activity添加到task stack的顶端并将其设置为前台任务.
ActivityStackSupervisor.resumeTopActivitiesLocked()
ActivityStack.resumeTopActivityInnerLocked()
暂停当前显示的activity
ActivityStackSupervisor.startSpecificActivityLocked()
判断是否需要新建进程,如果不需要,则直接调用realStartActivityLocked启动activity,需要就调用startProcessLocked创建进程。我们这里需要创建进程。
ActivityManagerService.startProcessLocked()

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

目标应用进程:

创建新进程,并执行新进程的ActivityThread.main()方法
ActivityThread.attach()
从main进入attach()后,再通过Binder进入AMS的attach()方法,并将新进程的ApplicationThread对象传给AMS,ApplicationThread是一个binder,用于后期AMS给目标进程注册binder死亡通知和与其IPC通信.

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

system_server进程:

ActivityManagerService.attachApplicationLocked()
先给目标进程的ApplicationThread注册binder死亡通知,然后初始化目标进程的ProcessRecord,再通过从目标应用进程传递过来的ApplicationThread对象进入目标进程并初始化目标进程的运行环境。
ActivityStackSupervisor.attachApplicationLocked()
最后在ActivityStackSupervisor.realStartActivityLocked()方法里面进入目标应用进程.

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

目标应用进程:

ActivityThread.handleLaunchActivity()
首先调用performLaunchActivity()加载activity实例,并创建application,contextImpl和config等运行环境并通过activity.attach()方法将这些对象保存在activity实例内部,以便activity可以访问。
在activity.attach()里面首先创建了与activity对象关联的PhoneWindow对象,然后创建WindowManagerImpl对象,用于本地端窗口管理。
attach()方法执行结束后回调Activity的onCreate()和onStart()方法。在应用重写onCreate()方法的时候,通过调用PhoneWindow.setContentView()方法创建activity的根视图DecorView并加载布局文件,将layout.xml文件解析出来后作为子view添加到DecorView中.
至此,activity的对象实例,对应的PhoneWindow对象和DecorView对象都已经创建完成。
接下来调用handleResumeActivity()方法将activity显示出来.
该方法首先调用performResumeActivity告诉activity进入resume状态并回调onResumed()方法。
然后调用WindowManager.addView()方法创建ViewRootImpl并与WindowManager.LayoutParams和DecorView关联。
最后调用ViewRootImpl.setView()方法,该方法首先调用requestLayout()方法请求UI做第一次布局,在requestLayout()方法调用ViewRootImpl.performTraversals()方法,在该方法里面依次调用performMeasure(),performLayout(),performDraw()对视图进程测量布局和绘制;然后调用IWindowSession.addToDisplay()方法向WMS请求给当前窗口创建一个WindowState;最后创建与InputManager的链接以便接收键盘和屏幕事件。
到此activity就启动完成,并显示到界面上。

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

总结:
在新进程中启动activity总体可分为5个阶段:
1. 启动进程调用startActivity()
2. AMS做一系列的准备工作:
   1) 解析intent并保存在activityInfo中
   2) 如果有多个activity满足要求,则弹出对话框让用户选择
   3) 根据启动模式进行任务栈的操作,找出或创建activity应该属于的任务栈,并将activity放到栈顶
   4) 暂停当前显示的activity
   5) 创建新进程
3. 执行新建进程的ActivityThread.main()方法, 然后attach到AMS,并将新进程的ApplicationThread对象传给AMS.该对象是个binder代理对象.
4. AMS再做几件事:
   1) 给目标进程的ApplicationThread对象注册binder死亡通知
   2) 创建目标进程的ProcessRecord.
   3) 初始化目标进程的运行环境
5. 进入目标进程创建并显示activity
   1) 加载activity实例,并创建application,contextImpl和config等对象.
   2) 创建与activity关联的PhoneWindow和WindowManagerImpl对象
   3) 回调activity的onCreate()和onStart()方法
   4) 在onCreate()方法中调用setContentView()方法创建activity的根视图DecorView并加载layout文件到DecorView.
   5) 回调activity的onResume()方法,然后创建ViewRootImpl并调用setView方法进行界面的绘制
   6) 创建与InputManager的连接以便接收键盘和触摸屏事件.

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Binder死亡通知机制:
进程在运行过程中可能异常退出,就会导致运行在进程里面的binder代理对象和binder本地对象异常死亡,比较严重的是binder本地对象的死亡会导致binder代理对象的无效.binder死亡通知机制就是为了解决这个问题而设计的.
死亡通知机制会监控到binder本地对象的死亡事件,然后通知引用了这些binder本地对象的binder代理对象.在这机制中binder代理对象会向binder驱动注册一个死亡接收通知,binder驱动监控binder本地对象死亡后就会通知对应的binder代理对象.binder代理对象在不需要接收死亡通知的时候,可以注销.


阅读更多
换一批

没有更多推荐了,返回首页