编程进阶网编程进阶网
  • 基础组成体系
  • 程序编程原理
  • 异常和IO系统
  • 六大设计原则
  • 设计模式导读
  • 创建型设计模式
  • 结构型设计模式
  • 行为型设计模式
  • 设计模式案例
  • 面向对象思想
  • 基础入门
  • 高级进阶
  • JVM虚拟机
  • 数据集合
  • Java面试题
  • C语言入门
  • C综合案例
  • C标准库
  • C语言专栏
  • C++入门
  • C++综合案例
  • C++专栏
  • HTML
  • CSS
  • JavaScript
  • 前端专栏
  • Swift
  • iOS入门
  • 基础入门
  • 开源库解读
  • 性能优化
  • Framework
  • 方案设计
  • 媒体音视频
  • 硬件开发
  • Groovy
  • 常用工具
  • 大厂面试题
  • 综合案例
  • 网络底层
  • Https
  • 网络请求
  • 故障排查
  • 专栏
  • 数组
  • 链表
  • 栈
  • 队列
  • 树
  • 递归
  • 哈希
  • 排序
  • 查找
  • 字符串
  • 其他
  • Bash脚本
  • Linux入门
  • 嵌入式开发
  • 代码规范
  • Markdown
  • 开发理论
  • 开发工具
  • Git管理
  • 百宝箱
  • 开源协议
  • 技术招聘
  • 测试经验
  • 职场提升
  • 技术模版
  • 关于我
  • 目标清单
  • 学习框架
  • 育儿经验
  • 我的专栏
  • 底层能力
  • 读书心得
  • 随笔笔记
  • 职场思考
  • 中华历史
  • 经济学故事
  • 基础组成体系
  • 程序编程原理
  • 异常和IO系统
  • 六大设计原则
  • 设计模式导读
  • 创建型设计模式
  • 结构型设计模式
  • 行为型设计模式
  • 设计模式案例
  • 面向对象思想
  • 基础入门
  • 高级进阶
  • JVM虚拟机
  • 数据集合
  • Java面试题
  • C语言入门
  • C综合案例
  • C标准库
  • C语言专栏
  • C++入门
  • C++综合案例
  • C++专栏
  • HTML
  • CSS
  • JavaScript
  • 前端专栏
  • Swift
  • iOS入门
  • 基础入门
  • 开源库解读
  • 性能优化
  • Framework
  • 方案设计
  • 媒体音视频
  • 硬件开发
  • Groovy
  • 常用工具
  • 大厂面试题
  • 综合案例
  • 网络底层
  • Https
  • 网络请求
  • 故障排查
  • 专栏
  • 数组
  • 链表
  • 栈
  • 队列
  • 树
  • 递归
  • 哈希
  • 排序
  • 查找
  • 字符串
  • 其他
  • Bash脚本
  • Linux入门
  • 嵌入式开发
  • 代码规范
  • Markdown
  • 开发理论
  • 开发工具
  • Git管理
  • 百宝箱
  • 开源协议
  • 技术招聘
  • 测试经验
  • 职场提升
  • 技术模版
  • 关于我
  • 目标清单
  • 学习框架
  • 育儿经验
  • 我的专栏
  • 底层能力
  • 读书心得
  • 随笔笔记
  • 职场思考
  • 中华历史
  • 经济学故事
  • 02.Android虚拟机知识
  • 03.App核心概念分析
  • 04.Android消息机制
  • 05.Android程序UI框架
  • 06.Android应用窗口
  • 07.WMS机制深入分析
  • 08.PMS机制深入分析
  • 09.AMS机制深入分析
  • 11.四大组件原理分析
  • 12.四大组件原理分析
  • 13.View绘制流程分析
  • 14.View渲染流程分析
  • 16.Android绘制原理
  • 17.Android事件传输
  • 18.Android事件拦截
  • 21.View自定义控件反思
  • 22.ViewGroup自定义控件
  • 25.IPC跨进程通信实践
  • 29.Binder机制的理解

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
      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
      image
贡献者: yangchong211
上一篇
09.AMS机制深入分析
下一篇
12.四大组件原理分析