Android内核三大核心功能之一AMS内部原理

上面类是AmS的全称,另外两大核心功能是WindowManagerService.java和View.java
AmS提供的主要功能:
统一调度各应用程序
内存管理
进程管理
AmS中定义了几个重要的数据类,分别用来保存进程(Process)、活动(Activity)和任务(Task)
ProcessRecord.java记录的进程的相关信息
该类中内部变量可分为三个部分,分别是进程文件信息、进程的内存状态信息和进程中包含的Activity、Service等。
该类在framework/base/services/java/com/android/server/am/路径下,该路径最后的am代表Activity Manager,和AmS有关的重要类都在该目录下。
ActivityRecord.java
AmS中使用ActivityRecord数据类来保存每个Activity的信息。History中包含一个int task变量,保存该Activity所属哪个任务。可以使用Intent.FLAG_NEW_TASK标识告诉AmS为启动的Activity重新创建一个Task 。
TaskRecord.java
AMS中使用任务的概念确保activity启动和退出的顺序
AmS中重要调度相关变量
// How long we wait until we timeout on key dispatching.
按键无响应的超时时间,这是google的标准,国内的联想手机大部分按照这个标准设计,华为手机不是按照这个标准
static final int KEY_DISPATCHING_TIMEOUT = *;
// Maximum number of recent tasks that we can remember.
static final int MAX_RECENT_TASKS = ;AMS记录的activity的最大数量,超过20则会舍弃最早记录的Activity
static final int BROADCAST_TIMEOUT=*1000广播超时时间
final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
= new ArrayList<PendingActivityLaunch>();暂时保存客户端请求
static final int PAUSE_TIMEOUT=500
AmS通知应用进程暂停指定的Activity,
AmS的忍耐是有限的,只有500毫秒。
如果应用进程在该常量时间内还同有停止,
AmS就是强制暂停关闭该Activity。
这就是为什么应用程序设计时,不能在onPause()不能做过多事情的原因。 activityStack就是存放activity信息的栈
相关变量:
final ArrayList mHistory=new ArrayList();保存了所有正在运行的Activity。
private final ArrayList mLRUActivities=new ArrayList ();
LRU(Latest Recent Used),保存所有过去使用过的Activity
统一调度各应用程序activity
Activity并不对应一个应用程序,ActivityThread才对应一个应用程序,所以Android允许同时运行多个应用程序,实际是是允许多个ActivityThread同时运行。
在Android中,Activity调度的基本思路是这样的:各应用进程要启动新的Activity或者停止当前的Activity,都要首先报告给AmS,而不能“擅自处理”。AmS在内部为所有应用进程都做了记录,当AmS接到启动或停止的报告时,首先更新内部记录,然后再通知相应客户进程运行或者停止指定的Activity。由于AmS内部有所有Activity的记录,也就理所当然地能够调度这些Activity,并根据Activity和系统内存的状态自动杀死后台的Activity
自己总结:activity启动或停止通知AmS,Ams决定是否执行动作,activity的数量>20时,最早入栈的activity会被AmS给忘记,新加进来了activity入栈
startActivity时底层工作图

以点击A-B为例:
点击A时,当AmS收到客户请求startActivity()后,会首先暂停当前的Activity,因此要判断mResumedActivity是否为空。在一般情况下,该值都不为空,如果不为空AmS会通知所在客户端暂停,执行该Activity并返回。
当A进程完成暂停后,报告AmS,这时AmS开始执行completePaused(),该方法中先要检查目标Activity是否在mHistory列表中,如果在,说明目标进程还在运行,目标Activity只是处于stop状态,还有没有finish,所以通知B进程直接resume指定的Activity即可。
Activity四种启动模式分析
android:launchMode设置是在AndroidManifest.xml文件中
分别为standard(默认),singleTop,singleTask,singleInstance
<activity android:name="com.example.android_launchmodel.Activity1"
android:launchMode="standard"/>默认 <activity android:name="com.example.android_launchmodel.Activity2"
android:launchMode="singleTask"/>
<activity android:name="com.example.android_launchmodel.Activity3"
android:launchMode="singleTop"/>
<activity android:name="com.example.android_launchmodel.Activity4"
android:launchMode="singleInstance"/>
standard
这是默认模式,每次激活Activity时都会创建Activity实例,并放入任务栈中
singleTop
如果在任务的栈顶正好存在该Activity的实例,就重用该实例( 会调用实例的 onNewIntent() ),否则就会创建新的实例并放入栈顶,即使栈中已经存在该Activity的实例,只要不在栈顶,都会创建新的实例
singleTask
如果在栈中已经有该Activity的实例,就重用该实例(会调用实例的 onNewIntent() )。重用时,会让该实例回到栈顶,因此在它上面的实例将会被移出栈。如果栈中不存在该实例,将会创建新的实例放入栈中
补充一个实例,建4个activity类(如上AndroidManifest.xml文件activity2为singleTask模式)在onCreate,onStart,onPause,onStop,onDestroy方法调用日志
Activity启动顺序为
Activity1à Activity2à Activity3à Activity4à Activity2

当activity1入栈--》activity2入栈--》activity3入栈--》activity4入栈--(在activity4中打开activity2因为设置activity2是singleTask模式,会在task任务栈中查找有没有activity2实例,找到了。接下来就是把activity2实例放到栈顶,但是activity2实例上面还有activity3和4的实例,怎么办!只能让他们出栈了。)
--》可以看到activity3和Activity4的onDestroy()方法被执行了
而Activity4启动Activity2时,activity2的onCreate()没有被执行(这也说明AmS没有重新创建activity2实例放入到task栈中,oncreate()方法只有在activity第一次被创建时才会被调用)
说明栈中Activity3和Activity4已经出栈,栈中Activity2实例被启动了
再按两次返回键后也返回到桌面了

至此栈内没有activity1和activity2的实例(其他类似)
singleInstance
在一个新栈中创建该Activity的实例,并让多个应用共享该栈中的该Activity实例。一旦该模式的Activity实例已经存在于某个栈中,任何应用再激活该Activity时都会重用该栈中的实例( 会调用实例的 onNewIntent() )。其效果相当于多个应用共享一个应用,不管谁激活该 Activity 都会进入同一个应用中。该模式下,不会再有新的Acitvity实例压入到栈里面,其它地方和'singleTask'一样。这意味着,栈中只有唯一的一个Activity实例。这是一个非常特殊的模式,这只能用在只有唯一的一个Activity的程序中。
借鉴下其他实例:http://blog.csdn.net/liuhe688/article/details/6754323
AmS内存回收规则
1、前台进程,是指那些与用户操作的相关进程。具体包括:
- 正在与用户交互的Activity
- 包含一个Service,该Service正在服务于和用户交互的Activity。
- 包含一个Service,该Service正在执行onCreate(),或者onStart(),onDestory()方法。
- 包含一个BroadcastReceiver,正在执行onReceive()函数。
2、可视进程,尽管没有和用户交互,但可以影响到用户所看到的内容。
- 一个位于Activity上的对话框
- 一个Service
3、服务进程:凡是使用startService()所启动的服务其所有的进程都称为服务进程。
4、空进程:进程不包含任何componet,包括Activity,Service,Receiver对象,之所以保留这些进程的原因是为了减少重新创建进行需要的开销。
Activity生命期的代码含义
在过去的应用开发过程中,大多数人已经 了解Activity生命期中的主要几个状态,并知道如何在这些状态中做不同的事情。但可能还有一些疑惑,比如onStart()方法和onStop方法的真正差异在哪里。尽管你知道onStop代表Activity的停止,onStart代表Activity的开始。问题是开始和停止的差别又在哪里?
Android内核三大核心功能之一AMS内部原理的更多相关文章
- PPT鼠绘必须掌握的PPT绘图三大核心功能
在PPT制作教程栏目中,陆陆续续的分享了一系列通过合并形状功能来绘图的教程,绘制安卓机器人.绘制西瓜.绘制鸡蛋.其实,合并形状功能只是PPT绘图的一部分,而真正想要掌握PPT鼠绘,仅仅是会使用合并形状 ...
- 《深入理解Android内核设计思想》
<深入理解Android内核设计思想> 基本信息 作者: 林学森 出版社:人民邮电出版社 ISBN:9787115348418 上架时间:2014-4-25 出版日期:2014 年5月 开 ...
- 本书版权输出到台湾地区,《深入理解Android内核设计思想》诚挚感谢大家一直以来的支持!
- Android内核剖析(1)
Linux的启动过程 开机上电执行bootloader,将内核的前n条指令加载到系统内存中------>系统内核的初始化----------->启动应用程序. bootloader的位置装 ...
- Android内核开发:系统启动速度优化-Android OS启动优化(转)
Android系统的启动优化主要分为三大部分: (1) Bootloader优化 (2) Linux Kernel的剪裁与优化 (3) Android OS部分的剪裁与优化 本文重点关注Android ...
- Android应用的核心基础
Android4开发入门经典 之 第二部分:Android应用的核心基础 Android应用中的组件 Application Components Android应用中最主要的组件是: 1:Activ ...
- Android内核驱动程序的编写和编译过程
注意:涉及的代码为android内核代码而不是android源码. 在智能手机时代,每个品牌的手机都有自己的个性特点.正是依靠这种与众不同的个性来吸引用户,营造品牌凝聚力和用户忠城度,典型的代表非ip ...
- 【Mycat】Mycat核心开发者带你看尽Mycat三大核心配置文件
写在前面 在分布式数据库中间件领域,Mycat和ShardingSphere可以说是在开源界有着相当重要的位置,不少小伙伴也在问我:Mycat和sharding-jdbc哪个好呀!其实,就我本身而言, ...
- spring三大核心学习(一)---控制反转
记得当年大学时候,java的企业级框架还是ssh的天下(spring,struts和hibernate),但是现在,感觉spring已经完全把那两个框架甩在后边了.用spring的人越来越多,用str ...
随机推荐
- 10、ABPZero系列教程之拼多多卖家工具 拼团提醒逻辑功能实现
上篇文章已经封装好了类库,现在继续实现功能,在ABPZero框架的基础上来实现一个完整的功能. Redis缓存 编写功能前先在本机安装好Redis,需要用到Redis做缓存,以下分享2个Windows ...
- JAVA入门(1.JAVA平台应用 2.核心概念:JVM,JDK,JRE 3.搭建JAVA开发环境 4.学习JAVA的原则)
主要内容: 1.JAVA平台应用 2.核心概念:JVM,JDK,JRE 3.搭建JAVA开发环境 4.学习JAVA的原则 JAVA的平台应用 JAVA的平台应用分为3个部分: 一.JAVA SE,主要 ...
- JSR-303校验类型
空检查 @Null 验证对象是否为null @NotNull 验证对象是否不为null, 无法查检长度为0的字符串 @NotBlank 检查约束字符串是不是Null还有被Trim的长 ...
- 微信小程序登陆授权
小程序前端代码 function WXlogin(){ wx.login({ success: function (code) { wx.getUserInfo({ success:function( ...
- 全面总结: Golang 调用 C/C++,例子式教程
作者:林冠宏 / 指尖下的幽灵 掘金:https://juejin.im/user/587f0dfe128fe100570ce2d8 博客:http://www.cnblogs.com/linguan ...
- python模块安装
现在终于知道怎么在windows上导入Python的第三方模块了 首先在DOS下进入Python安装的pip目录:D:/Python27/Scripts 用pip install XXX安装 之前一直 ...
- 385cc412a70eb9c6578a82ac58fce14c md5破解
在线破解很方便,你可能几秒钟就可以破解得到MD5原码...但是在线破解也不是万能的 也有查不到的或者需要收费的(土豪略过这句话)...下面推荐个网站md5.geekzh.com 所有MD5免费查询 E ...
- 2017 Multi-University Training Contest - Team 9 1004&&HDU 6164 Dying Light【数学+模拟】
Dying Light Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Tot ...
- ZOJ3602:Count the Trees
我是在neuqvj上交的这题:http://vj.acmclub.cn/problem/viewProblem.action?id=17848 本来是挺容易的树同构题,可是节点数比较多,愣是把普通ha ...
- CodeForces776-A.Serial Killer-string
A Serial Killer time limit per test 2 seconds memory limit per test 256 megabytes input standard inp ...