11.四大组件原理分析
目录介绍
- 01.Activity启动流程
- 02.Activity布局创建
- 03.Activity布局渲染
- 04.Activity知识合集
- 05.Service知识合集
- 06.startService启动流程
- 07.bindService启动流程
01.Activity启动流程
1.1 Activity介绍
- 什么是Activity
- Activity并不负责视图控制,它只是控制生命周期和处理事件。真正控制视图的是Window。一个Activity包含了一个Window,Window才是真正代表一个窗口。
- Activity就像一个控制器,统筹视图的添加与显示,以及通过其他回调方法,来与Window、以及View进行交互。
1.2 流程图说明
- Launcher启动开启Activity流程
LauncherActivity#onListItemClick(),Launcher启动之后会将各个应用包名和icon与app的name保存起来,然后执行icon的点击事件的时候调用startActivity方法 LauncherActivity#intentForPosition(),这个是获取包名和类名。隐式启动,跨进程一般用intent隐式启动activity
- 应用的图标是怎么和这个应用的Lancher Activity联系起来的呢?
- 系统在启动的时候会启动PackageManagerService(包管理服务),所有的应用都是通过它安装的,PackageManagerService会对应用的AndroidManifest.xml进行解析,从而得到应用里所有的组件信息。
- 执行启动Activity重点逻辑,大概流程如下所示
ActivityStackSupervisor.attachApplicationLocked() ActivityStackSupervisor.realStartActivityLocked() IApplicationThread.scheduleLauncherActivity() ActivityThread.sendMessage() ActivityThread.H.sendMessage() ActivityThread.H.handleMessage() ActivityThread.handleLauncherActivity() ActivityThread.performLauncherActivity() Instrumentation.callActivityOnCreate() Activity.onCreate() ActivityThread.handleResumeActivity() ActivityThread.performResumeActivity() Activity.performResume() Instrumentation.callActivityOnResume() Activity.onResume() ActivityManagerNative.getDefault().activityResumed(token)
1.3 Activity如何创建
- ActivityThread接收到SystemServer进程的消息之后会通过其内部的Handler对象分发消息,经过一系列的分发之后调用了ActivityThread的handleLaunchActivity方法
ActivityThread#handleLaunchActivity(),这个是启动并创建activity的入口。
- ActivityThread中执行performLaunchActivity,从而生成了Activity的实例。
ActivityThread#performLaunchActivity(),创建Activity类型上下文Context然后创建activity对象 ActivityThread#mInstrumentation.newActivity(),这里是通过反射去创建Activity对象 ActivityThread#performLaunchActivity中activity.attach,这里是会最先执行Activity中的attach方法,这里面会创建PhoneWindow操作 ActivityThread#mInstrumentation.callActivityOnCreate,这里最终会执行到Activity中的onCreate方法
02.Activity布局创建
2.1 Activity角色扮演
- Activity扮演了一个界面展示的角色
- 界面的布局文件是如何加载到内存并被Activity管理的?android中的View是一个怎样的概念?加载到内存中的布局文件是如何绘制出来的?
- Activity对界面布局的管理是都是通过Window对象来实现的
- Activity从用户角度就是一个个的窗口实例,因此不难想象每个Activity中都对应着一个Window对象,而这个Window对象就是负责加载显示界面的。
- 至于window对象是如何展示不同的界面的,那是通过定义不同的View组件实现不同的界面展示。
2.2 Activity布局流程
- handleLaunchActivity入口
- 当ActivityManagerService接收到启动Activity的请求之后会通过IApplicationThread进程间通讯告知ApplicationThread并执行handleLauncherActivity方法。
- 布局流程源码思路大概如下所示
ActivityThread#handleLaunchActivity(),这个是分析的入口 ActivityThread#performLaunchActivity(),通过反射的机制创建的Activity,并调用了Activity的attach方法 Activity#attach(),在attach方法这里初始化了一些Activity的成员变量,最重要是创建PhoneWindow对象 ActivityThread#performLaunchActivity#mInstrumentation.callActivityOnCreate,Instrumentation就是具体操作Activity回调其生命周期方法的 Activity#performCreate(),开始执行onCreate的生命周期方法,这个是分析布局流程入口。在该方法中,调用setContentView设置布局
- 然后在onCreate设置布局流程
Activity#super.onCreate(),做了一些Activity的初始化操作,如果不调用super方法,在performLaunchActivity中会抛出没有调用super异常 Activity#setContentView(),看到Activity类中设置view的方法,调用了getWindow(),其实最终就是PhoneWindow实例 PhoneWindow#setContentView(),判断布局是否为空,然后这里面主要是加载布局 PhoneWindow#installDecor(),创建一个DecorView,它相当是Activity中的 PhoneWindow#generateLayout(),这个里面是将状态栏,content布局,titleBar,theme主体等一些属性添加到DecorView中。 PhoneWindow#setContentView#mLayoutInflater.inflate(layoutResID, mContentParent),这个相当于把自定义布局解析后添加到content布局中
- Activity中布局层次
- mDector --> mContentRoot --> mContentParent --> 自定义layoutView
- mDector是Activity页面上根布局DecorView,mContentParent官方主题布局中提供给用户装载布局的容器
03.Activity布局渲染
- Activity中页面渲染的入口
- Android体系在执行Activity的onResume方法之前会回调ActivityThread的handleResumeActivity。
- 然后看一下Activity布局展示可见的流程
ActivityThread#handleResumeActivity(),设置WindowManager属性,获取了Activity的Window相关参数之后执行了r.activity.makeVisible()方法 Activity#makeVisible(),这里面逻辑是是将mDecor给显示到界面上,只会执行一次。然后设置VISIBLE让布局可见。
- 然后再看一下Activity布局渲染流程
Activity#makeVisible#getWindowManager(),根据WindowManagerImpl --> WindowManager --> ViewManager,最终可知vm是WindowManagerImpl的实例 Activity#makeVisible#wm.addView(),具体看WindowManagerImpl的addView方法 WindowManagerImpl#addView(),在这个类中可以看到调用了mGlobal.addView(),而mGlobal是WindowManagerGlobal的对象。 WindowManagerGlobal#addView(),这里面逻辑很核心,创建ViewRootImpl对象,这个是布局渲染的核心类 WindowManagerGlobal#addView#root.setView(),实现了root与ViewRootImpl的关联 ViewRootImpl#setView()#requestLayout(),在ViewRootImpl的setView方法中,调用requestLayout执行重绘的请求
04.Activity知识合集
- Activity堆栈,由ActivityManagerService维护
image
4.1 Activity栈管理
- 栈管理的简单介绍
- 一个应用程序通常包含多个Activity。每个Activity在设计时都应该以执行某个用户发起的 action 作为核心目标,并且它能启动其它Activity。
- Task就是多个Activity的集合,用户操作时与Activity进行交互。这些Activity根据启动顺序压入task中,如果pop task 是按照先进后出的顺序pop。
- Task任务栈的管理
- Activity依照顺序压入Task并按照“先进后出”的顺序pop,对Task的管理显得十分的必要。
- taskAffinity属性:如果不设置此属性,默认一个应用程序只有一个栈,这个栈以应用包命为单位。task对于Activity来说就好像它的身份证一样,可以告诉所在的task,自己属于这个task中的一员;拥有相同affinity的多个Activity理论同属于一个task,task自身的affinity决定于根Activity的affinity值。
- affinity在什么场合应用呢?1.根据affinity重新为Activity选择宿主task;2.启动一个Activity过程中Intent使用了FLAG_ACTIVITY_NEW_TASK标记,根据affinity查找或创建一个新的具有对应affinity的task
- ActivityTask和Activity栈管理
- http://www.lxiaoyu.com/p/324616
- https://blog.csdn.net/heng615975867/article/details/108725469
05.Service知识合集
- service的生命周期图
image