Activity堆栈管理

前言

AMS

AMS(Activity Manager Service)是系统进程的一部分,是 Binder Server,用于管理、记录、查询运行的组件信息。
AMS 是管理Activity和组件运行状态的系统进程,主要功能如下:

  1. 组件状态管理(四大组件)
  2. 组件状态查询
  3. Task相关操作
  4. 其他操作(系统运行时信息,如内存、cpu信息,的查询等)

通过以下方法获取ActivityManager对象,进而获取相关信息。
ActivityManager ams = (ActivityManager) activity.getSystemService(Context.ACTIVITY_SERVICE);

App启动流程

Android系统是基于Linux系统的,原则上说它的应用程序并不只是apk一种,能运行在Linux系统上的应用程序通过一定的方式都能运行在Android系统上,一些系统级别的应用程序就是这种形式存在的。

通常app有两种启动途径

  1. 在Launcher中点击应用图标启动
  2. 通过startActivity启动。

启动流程

  1. AMS --> startActivity()
  2. ApplicationThread.schedulePauseActivity()ActivityThread.handlePauseActivity()
  3. WMS --> remove from window
  4. 当前Activity activityPausedcompletePauseLocked
  5. 处理启动新Activity流程,attachApplicationrealStartActivityLocked
  6. ApplicationThread.scheduleLaunchActivity()performLaunchActivity
  7. Activity.attach()Activity.onCreate()

一、Activity状态管理、Task管理

这里参照官方说明吧,很详细。

系统停止您的一个 Activity 时(例如,新 Activity 启动或任务转到前台),如果系统需要回收系统内存资源,则可能会完全销毁该 Activity。 发生这种情况时,有关该 Activity 状态的信息将会丢失。如果发生这种情况,系统仍会知道该 Activity 存在于返回栈中,但是当该 Activity 被置于堆栈顶部时,系统一定会重建 Activity(而不是恢复 Activity)。 为了避免用户的工作丢失,您应主动通过在 Activity 中实现 onSaveInstanceState() 回调方法来保留工作。

二、注意事项

Android 不仅能装载很多组件,而且能把这些组件跨进程地组成ActivityTask,这个特性使得每个App都不是孤立的,从而能最大限度地实现资源复用。

Activity列表 描述
mHistory 历史栈
mLRUActivities 最近最少访问的Activity
mStoppingActivities 已经stopped的Activity
mGoingtoSleepActivities 无操作即将进入睡眠状态的Activity
mNoAnimActivities 无需启动动画的Activity
mFinishingActivities 执行了finish()方法的Activity

如果 Activity A 启动 Activity B,则 Activity B 可以在其清单文件中定义它应该如何与当前任务关联(如果可能),并且 Activity A 还可以请求 Activity B 应该如何与当前任务关联。如果这两个 Activity 均定义 Activity B 应该如何与任务关联,则 Activity A 的请求(如 Intent 中所定义)优先级要高于 Activity B 的请求(如其清单文件中所定义)。

清单文件配置影响Task

属性 描述
taskAffinity 一个task的taskAffinity值取决于它的根Activity。新建Task时,该Activity设置的taskAffinity属性才能决定它所在task的taskAffinity属性。
清单文件中可配置Application或Activity的属性taskAffinity,取值规则符合包名规则(至少包含一个点),默认值就是包名。
allowTaskReparenting 动态转移,默认情况下Activity A 启动时会被放置在与启动它的Activity B相同的栈中,而此时另一个栈被移到前台并且启动了前面已经启动的Activity A,此时默认情况下Activity A还是保持在之前的栈中。而如果Activity在清单文件中设置了android:allowTaskReparenting="true"属性值时,Activity A就会被移动到当前启动它的栈中。
clearTaskOnLaunch 只对root Activity有效,值为true时,启动Activity会清空目标栈中除了自身以外的Activity
alwaysRetainTaskState 用户在一定时间内不再访问Task,比如30分钟,系统会清除task中的Activity(root Activity除外),而设置该值为true,可以改变这种情况。
finishOnTaskLaunch 每当用户再次启动其任务(在主屏幕上选择任务)时,是否应关闭该 Activity 实例 —“true”表示应关闭,“false”表示不应关闭。 默认值为“false”。
如果该属性和 allowTaskReparenting 均为“true”,则优先使用该属性。
noHistory 该Activity将不会被保存在History Stack中。

启动时Intent的Flag影响Task

Flag 描述
FLAG_ACTIVITY_NEW_TASK 等同于singleTask模式。以下flag需要与这个flag一起用。
FLAG_ACTIVITY_CLEAR_TASK:清除栈中其他Activity。
FLAG_ACTIVITY_TASK_ON_HOME:新启动的Activity放在task栈中Launcher的上面。
FLAG_ACTIVITY_MULTIPLE_TASK:阻止系统恢复一个现有的task,也就是每次都新启动一个task。
FLAG_ACTIVITY_LAUNCH_ADJACENT:仅用于分屏多窗口模式,新启动的Activity显示在启动它的Activity旁边,如果需要创建现有Activity的新实例,应同时设置FLAG_ACTIVITY_MULTIPLE_TASK
FLAG_ACTIVITY_SINGLE_TOP 等同于singleTop模式。
FLAG_ACTIVITY_CLEAR_TOP 如果要启动的Activity已经在栈中,那么需要清除在该Activity之上的所有Activity,并通过onNewIntent()方法将Intent传递给该Activity
FLAG_ACTIVITY_NO_HISTORY 该Activity将不会被保存在History Stack中。
FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS 该Activity不会被放在系统最近启动的Activity列表中。
如进程列表截图中不会有这个页面(会获取上一个页面的截图)
按home键回到桌面后,在点击桌面图标应用重新回到前台时,也不会显示这个页面,而是显示上一个页面。
FLAG_ACTIVITY_RESET_TASK_IF_NEEDED 无论Activity的目标task是新task还是现有task,都会处于task的上端。
一般要FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET标识配合使用,不过该标识 API 21 以后过时,FLAG_ACTIVITY_NEW_DOCUMENT取代之。
该Activity启动时,如果目标栈中已经有该Activity,那么清除其上面的所有Activity。

附:参考

官方文档
深入理解Android内核设计思想.林学森
SDK源码

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,826评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,968评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,234评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,562评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,611评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,482评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,271评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,166评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,608评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,814评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,926评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,644评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,249评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,866评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,991评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,063评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,871评论 2 354

推荐阅读更多精彩内容