美文网首页
Activity堆栈管理

Activity堆栈管理

作者: Hdib | 来源:发表于2019-08-16 15:05 被阅读0次

    前言

    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源码

    相关文章

      网友评论

          本文标题:Activity堆栈管理

          本文链接:https://www.haomeiwen.com/subject/hwtqsctx.html