继续来研究Android Framework层相关的一些东东,这里是以Android8.0版本的源码进行梳理的,关注的还是其核心流程,不是彻底分析,了解了核心流程是为了了期其大概的原理。

Android系统启动:

这里具体就不分析代码了,因为重点是来分析AMS相关的代码,这里以流程图的方式来展现一下整个的启动,毕境对于一个组件的启动得要建立在整个Android系统启动基础之上的,另外这块的具体源码也不敢看,还没达到这种能直接分析底层的能力,所以先从大局观来了解其流程,下面开始:

接着就启动Linux内核了:

然后再启动init进程:

接着则启动咱们熟知的Zygote进程了:

接下来则启动各种服务了:

而其中当启动了AMS服务之后,则就会启动Launch应用程序了,如下:

我们知道以上服务最终都得到ServiceManager进行注册,因为其实都是一个Binder通信的过程,所以再来复习一下ServiceManager的启动流程。

Binder机制ServiceManager启动:

那知道了ServiceManager何时启动的,接下来重点来看一下咱们这次要研究的AMS(ActivityManagerService)它是怎么注册ServiceManager上的。

AMS注册流程:

其中ServiceManager就是一个服务端的角色,而AMS则是一个客户端的角色。

应用程序启动:

在知道了AMS服务器注册过程之后,接下来则看一下一个Android应用是如何启动的,先来贴一张流程图:

好,接下来分析一下相关的源码,看一下是否如流程图所示,这里还是采用在线的androidxref.com上来进行源码分析,我电脑本地木有下载,省点事:

首先来看一下Zygote进程的启动:

然后它里面有一个main主入口函数:

也就是之前Android系统启动流程图这块所示:

最后则开启死循环来等待Ams的请求,如下:

其实也就是对应这个流程:

好,接下来再来分析一个应用是如何启动的,按流程图上的来:

那就定位到AMS中:

然后:

其中可以看到里面会传要启动应用的各种信息:

然后跟进去瞅一眼:

也就是到了这一步:

流程也就到了这:

其中可以看到设置了一系列的参数:

然后再下一步:

对应代码:

注意上面是“Zygote主模式”,好,如果这个条件不匹配,则会继续往下执行,如下:

好,如果连接成功,则流程会走到了:

而最终的代码在这:

此时我们所熟知的ActivityThread的main()方法就会被调用了,然后整个应用就启动了。

Activity启动:

根Activity启动:

这里先回顾一下整个Android系统启动流程的这一步,串一下:

此时我们点击Launch应用中的某个图标,则会启动该应用的根Activity,其整个流程先看一下流程图:

好,依据此流程来看一下对应的源代码:

此时就会创建Application:

最终会调到这:

走进去瞅一下它的细节:

然后再跟进去:

而对于一些Activity的其它生命周期的启动都是通过ActivityThread中的Handler来实现的:

普通Activity启动:

Intrumentation.execStartActivity()【未跨进程】:

对于Activity的启动我们肯定得要调用startActivity()方法,所以咱们就从这个方法为入口逐一来剖析其里面的机理,还是很复杂的,下面开始:

所以接下来看一下Instrumentation的启动细节:

ActivityManagerProxy.startActivity()【未跨进程】:

而这个ActivityManagerNative在之前https://www.cnblogs.com/webor2006/p/11811650.html分析Binder机制见过,如下:

其实它也是一个典型的AIDL的Binder通信,打开再来瞅一下:

然后它里面还有一个Proxy:

此时就会调用到Proxy中的startActivity()方法进行Binder通讯了:

此时就会通过Binder驱动调用它的Stub的onTransact()的方法,如下:

ActivityManagerService.startActivity()【开始跨进程了】:

此时就会调用ActivityManagerService的startActivity方法,因为它是ActivityManagerNative的具体实现类:

此时,就到了跨进程访问了,在这之前都是在本进程的逻辑,好接下来继续分析:

ActivityStackSupervisor.startActivityMyWait():

其中看注释说明,是切换到用户app的栈了,我们知道Android的Activity是以栈的形式来管理的,所以它是比较核心的了,可以大致看一下它里面有一些栈的管理:

这个栈的管理在之后的分析中还会有提及到,先有个大致印象,先来关注主流程:

而其实又是一个AIDL的过程,进去稍看一下它的细节:

而看一下它具体的实现:

就是从ServiceManager中来找到package相关的服务,标准的AIDL的调用过程,那IPackageManager的具体实现类是哪个呢?其实是这个,也就是继承了IPackageManager中的抽象类Stub的实现类,其实是它:

PackageManagerService.resolveIntent():扫描app,注册组件

那看一下它的resolveIntent()方法:

查看一下这个方法的细节:

然后回到resolveIntent()方法来,则会看到有一个根据优先级来选择最佳的ResolveInfo,如下:

好,这里还得再来说一下PackageManagerService这个很重要的服务,主要是管理包的一些信息,我们知道在apk安装到系统中时,会在/data/app之类的系统目录下存在,而该服务则会扫描注册在清单中的一些包信息,那么看一下构造方法就能找到一些相关的信息,如下:

所以可以看到该服务器就是来扫描一些包的信息用的,而这构造函数的调用是在这里:

所以这也是为啥在之前这块可以看到拿服务就是用的"package"这个key,回忆下:

其实Android的很多核心服务都是这样会往ServiceManager去注册的。

ActivityStackSupervisor.startActivityLocked():验证intent、Class、Permission等,保存将要启动的Activity的Record

好,接下来接着主流程继续:

那看一下它的细节,可以看到各种异常检测,这里截其中一小部分:

最终生成一个ActivityRecord对像来保存相关信息:

ActivityStackSupervisor.startActivityUncheckedLocked():检查将要启动的Activity的launchMode和启动Flag,根据launcheMode和Flag配置task

该方法的实现代码也比较多,就瞅一下它的大致细节既可:

里面真的是非常之复杂,也看不懂,有个大体的了解,重点是了解整个主流程的过程,好继续,直接跳到这方法的最后:

ActvityStack.startActivityLocked:任务栈历史栈配置

它是专门来维护任务栈的进出的,而上面的ActivityStackSupervisor是维护各个栈的信息,职责不一样,那下面来看一下该方法的细节:

在最后:

此时又回到了ActivityStackSupervisor了,如下:

也就是如下:

ActivityStack.resumeTopActivityInnerLocked():查找要进入暂停的Activity

这个里面实现的代码理非常之多,只看核心的,在要跳转到新的Activity之前,先会把一些Activity给暂停了,瞅一下这块的核心流程:

然后在跳到新Activity之前,会先暂停当前的Activity,如下:

ActivityStack.startPausingLocked():通过ipc告诉要暂停的Activity进入暂停

此时看一下这个方法的细节:

而prev.app.thread其实就是ActivityThread,而它里面其实是一个IPC的过程,如下:

此时就会到了ActivityThread中的消息处理中心了,如下:

ActivityThread.handlePauseActivity():

下面具体看一下它的实现:

1、正式让之前的Activity暂停:

2、告诉AMS已经暂停完成:

回到这个方法继续执行,就会发现:

而最终会调到ActivityManagerService,如下:

ActivityManagerService.activityPaused():

然后就会调用到ActivityStack.activityPausedLocked()方法。

ActivityStack.activityPausedLocked():

其中这个方法有一个resumeNext参数,传的true,这里想一想就明白其意思,暂停了当前显示的Activity之后,那肯定得要将要跳转的Activity给显示呀,而这个参数就是控制要显示跳转的Activity的逻辑的,如下:

ActivityStackSuperVisor.resumeTopActivitiesLocked():

ActivityStack.resumeTopActivityLocked():验证是否该启动的Activity所在进程和app是否存在,若存在,直接启动,否则,准备创建该进程。

然后在这个方法里面则会有一个关键的逻辑判断,在启动新的Activity时,先判断是否该Activity是在同一个进程:

如果为ture则代码要启动的Activity为同一个进程,这里就不细看了,如果条件不满足则代表进程不存在,需要创建进程,这里瞅一下,如下:

ActivityStackSuperVisor.startSpecificActivityLocked():该进程不存在,创建进程

好,又回到了这个栈管理类了,看一下它的细节:

ActivityManagerService.startProcessLocked():通过Process.start(“android.app.ActivityThread”)启动进程

ActivityThread.main():

当进程被启动之后,则该进程的ActivityThread.main()方法就会被执行,这块就比较熟了。主要是创建一个Looper。

ActivityThread.attach():

IActivityManager.attachApplication():

而上面的attach的具体实现:

会调用IActivityManager.attachApplication()方法了,此时就会调用ActivityServiceManager.attachApplication(),如下:

然后往这个方法找一下,会有如下核心代码:

ActivityStackSuperVisor.attachApplicationLocked():准备启动应用,先查找MainActivity

此时又回到了这个栈管理大管家,瞅下:

ActivityStackSuperVisor.realStartActivityLocked():IPC通知ActivityThread

ActivityThread.scheduleLaunchActivity():

其中performLaunchActivity方法就是来创建要启动的Activity,稍微看一下细节:

至此关于Activity的启动的主流程就分析完了,太TM复杂了。。可以看到Android底层的代码有很多C/S架构、分模块的思想,真的是博大精深。。

Service启动:

接下来再来分析Android的另一大组件的启动---Service,先来贴一下大体的主流程图:

好,下面来瞅一下源码:

具体细节就不看了,最终会调到ActivityThread的这块:

还有其它相关的一些跟服务相关的东东在里面,大致贴一下:

Android AMS服务的更多相关文章

  1. Android PKMS服务

    它的作用? 关于PKMS的全称是啥应该咱们不陌生,PackageManagerService,和AMS一样是Android系统的核心服务,它主要负责系统中Package的管理,应用程序的安装.卸载.信 ...

  2. 3D语音天气球(源码分享)——在Unity中使用Android语音服务

    转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! 开篇废话: 这个项目准备分四部分介绍: 一:创建可旋转的"3D球":3 ...

  3. Android从服务端获取json解析显示在客户端上面

    Android从服务端获取json解析显示在客户端上面 百度经验:jingyan.baidu.com 首先说一下Json数据的最基本的特点,Json数据是一系列的键值对的集合,和XML数据来比,Jso ...

  4. [Android] Service服务详解以及如何使service服务不被杀死

    排版上的细节有些不好看,主要是我用的MarkDown编辑器预览和这里的不一样,在那个上面的样式很舒服.这里要改的地方太多就不想改了,将就看吧.下次写的时候注意.还有看到错误给我提啊. 本文链接:htt ...

  5. Android 前台服务

    Android 前台服务 学习自 https://blog.csdn.net/guolin_blog/article/details/11952435#t3 前台服务漫谈 我们之前学习的Service ...

  6. Android Service 服务(三)—— bindService与remoteService

    (转自:http://blog.csdn.net/ithomer/article/details/7366396)   一.bindService简介 bindService是绑定Service服务, ...

  7. Android 位置服务——BaiduLocation的使用

    原文:Android 位置服务--BaiduLocation的使用 版权声明:本文为博主原创文章,欢迎转载,转载请在文章显眼处说明文章出处并给出连接. https://blog.csdn.net/To ...

  8. Android 网络服务介绍

    1. 介绍 Android网络服务主要包括如下四个部分 - ConnectivityService: 提供数据连接管理服务,包括移动数据.WIFI.以太网等 - NetworkPolicyManage ...

  9. Android - AMS源码分析

    Android核心分析之AMS App和AMS(SystemServer进程)还有zygote进程分属于三个独立的进程 App与AMS通过Binder进行IPC通信,AMS(SystemServer进 ...

随机推荐

  1. 记一次Pr中视频蜜汁卡顿往复和解决方法

    目录 问题 换素材的起因 灵异素材 无端联想 解决 问题 换素材的起因 本来视频剪了一晚剪完了,导出一看,好家伙,糊到上世纪.原来素材的像素大小都没法看,这视频素材我是从别人U盘拷过来的,可他竟然是用 ...

  2. Beta冲刺(1/7)——2019.5.23

    作业描述 课程 软件工程1916|W(福州大学) 团队名称 修!咻咻! 作业要求 项目Beta冲刺(团队) 团队目标 切实可行的计算机协会维修预约平台 开发工具 Eclipse 团队信息 队员学号 队 ...

  3. Ognl 使用实例手册

    上一篇博文介绍了ongl的基础语法,接下来进入实际的使用篇,我们将结合一些实际的case,来演示ognl究竟可以支撑到什么地步 在看本文之前,强烈建议先熟悉一下什么是ognl,以及其语法特点,减少阅读 ...

  4. Effective.Java第12-22条

    12.  始终重写toString()方法 如果不重写toString()方法,打印的时候是 类名+@+哈希码的无符号十六进制.我们查看 Object的toString()方法如下: public S ...

  5. windows版mysql安装

    https://blog.csdn.net/ycxzuoxin/article/details/80908447

  6. DDR3(3):写控制

    调取的 DDR3 控制器给用户端预留了接口,用于实现对该 IP 核的控制,本篇介绍一下 DDR3 IP核写.在生成 DDR3 IP 核的界面中,可以找到 User Guide 手册,DDR3 的使用将 ...

  7. 项目启动redis连接报错

    问题解决: 1)打开端口6379(修改iptabels文件) 2)关闭防火墙.(可能linux防火墙作用,限制了端口的出入) 3)修改redis.conf文件,将 bind 127.0.0.1这一行注 ...

  8. -Shell 教程 Bash 脚本 基础语法 MD

    目录 目录 Shell 简介 Shell 脚本 Shell 环境 第一个shell脚本 Shell 变量 定义变量 使用变量 只读变量 删除变量 Shell 字符串 单引号 双引号 字符串基本操作 S ...

  9. SUSE12SP3-Samba配置

    简介 samba官网:https://www.samba.org/ 维基百科: https://zh.wikipedia.org/wiki/Samba Samba,是种用来让UNIX系列的操作系统与微 ...

  10. 锤子剪刀布pat-1018

    题目描述 大家应该都会玩“锤子剪刀布”的游戏:现给出两人的交锋记录,请统计双方的胜.平.负次数,并且给出双方分别出什么手势的胜算最大. 输入描述: 输入第1行给出正整数N(<=105),即双方交 ...