• AMS:ActivityRecord 理解


    什么是 ActivityRecord ?android 的解释是 An entry in the history task, representing an activity。大意是 ActivityRecord 是历史任务中的一个记录,代表着 activity,换言之,它是应用层的 activity 在 AMS 中的记录。

    那么这个记录,也就是 ActivityRecord 需要记录哪些东西呢 ?

    1、Activity 稳定不变的身份信息

    这类信息是每个 Activity 出生就确定的,且不会改变,标识着一个 activity 的身份。就好比人的出生信息。这些信息有 info、packageName、icon 等

     		 final ActivityInfo info; // activity info provided by developer in AndroidManifest
    439      // The package implementing intent's component
    440      // TODO: rename to mPackageName
    441      final String packageName;
    442      // the intent component, or target of an alias.
    443      final ComponentName mActivityComponent;
    		 private int icon;               // resource identifier of activity's icon.
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    2、Activity 启动时基本信息

    是指启动 Activity 时,才确定的信息,在每次启动时可能会不同。如 launchedFromPid、task、launchedFromPackage、processName。

    这样说还是挺抽象的,如果把启动 activity 比作人进行一次外出的话,这类信息就是出发地、目的地、出行方式,在计划这次出行后才能确定。

    		 final int launchedFromPid; // always the pid who started the activity.
    449      final String launchedFromPackage; // always the package who started the activity.
    455      final String processName; // process where this component wants to run
    469      private Task task;              // the task this is in.
    
    • 1
    • 2
    • 3
    • 4

    3、Activity 过程耗时信息

    在 activity 启动过程中,一些阶段的耗时信息。这类信息是只有阶段完成后才能统计确定。

    470      private long createTime = System.currentTimeMillis();
    471      long lastVisibleTime;         // last time this activity became visible
    472      long pauseTime;               // last time we started pausing the activity
    473      long launchTickTime;          // base time for launch tick messages
    474      long topResumedStateLossTime; // last time we reported top resumed state loss to an activity
    
    • 1
    • 2
    • 3
    • 4
    • 5

    4、Activity 当前状态信息

    这些信息好理解,也是比较重要的,记录 activity 当前的生命周期状态。 主要看下枚举类型 State。

    498      private State mState;    // current state we are in
    508      boolean stopped;        // is activity pause finished?
    
    566      enum State {
    567          INITIALIZING,
    568          STARTED,
    569          RESUMED,
    570          PAUSING,
    571          PAUSED,
    572          STOPPING,
    573          STOPPED,
    574          FINISHING,
    575          DESTROYING,
    576          DESTROYED,
    577          RESTARTING_PROCESS
    578      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    5、控制信息

    主要是一些过程回调的等待的 timeout 阈值定义,以及超时发生后的处理方法。与是哪个 activity 或哪次启动无关,对所有 activity 适用。

    (1)超时阈值

    // How long we wait until giving up on the last activity to pause.  This
    414      // is short because it directly impacts the responsiveness of starting the
    415      // next activity.
    416      private static final int PAUSE_TIMEOUT = 500;
    417  
    418      // Ticks during which we check progress while waiting for an app to launch.
    419      private static final int LAUNCH_TICK = 500;
    420  
    421      // How long we wait for the activity to tell us it has stopped before
    422      // giving up.  This is a good amount of time because we really need this
    423      // from the application in order to get its saved state. Once the stop
    424      // is complete we may start destroying client resources triggering
    425      // crashes if the UI thread was hung. We put this timeout one second behind
    426      // the ANR timeout so these situations will generate ANR instead of
    427      // Surface lost or other errors.
    428      private static final int STOP_TIMEOUT = 11 * 1000;
    429  
    430      // How long we wait until giving up on an activity telling us it has
    431      // finished destroying itself.
    432      private static final int DESTROY_TIMEOUT = 10 * 1000;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    (2)过程超时相关的回调,

    private final Runnable mPauseTimeoutRunnable = new Runnable() {
    936          @Override
    937          public void run() {
    938              // We don't at this point know if the activity is fullscreen,
    939              // so we need to be conservative and assume it isn't.
    940              Slog.w(TAG, "Activity pause timeout for " + ActivityRecord.this);
    941              synchronized (mAtmService.mGlobalLock) {
    942                  if (!hasProcess()) {
    943                      return;
    944                  }
    945                  mAtmService.logAppTooSlow(app, pauseTime, "pausing " + ActivityRecord.this);
    946                  activityPaused(true);
    947              }
    948          }
    949      };
    950  
    951      private final Runnable mLaunchTickRunnable = new Runnable() {
    952          @Override
    953          public void run() {
    954              synchronized (mAtmService.mGlobalLock) {
    955                  if (continueLaunchTicking()) {
    956                      mAtmService.logAppTooSlow(
    957                              app, launchTickTime, "launching " + ActivityRecord.this);
    958                  }
    959              }
    960          }
    961      };
    962  
    963      private final Runnable mDestroyTimeoutRunnable = new Runnable() {
    964          @Override
    965          public void run() {
    966              synchronized (mAtmService.mGlobalLock) {
    967                  Slog.w(TAG, "Activity destroy timeout for " + ActivityRecord.this);
    968                  destroyed("destroyTimeout");
    969              }
    970          }
    971      };
    972  
    973      private final Runnable mStopTimeoutRunnable = new Runnable() {
    974          @Override
    975          public void run() {
    976              synchronized (mAtmService.mGlobalLock) {
    977                  Slog.w(TAG, "Activity stop timeout for " + ActivityRecord.this);
    978                  if (isInHistory()) {
    979                      activityStopped(
    980                              null /*icicle*/, null /*persistentState*/, null /*description*/);
    981                  }
    982              }
    983          }
    984      };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50

    6、类比于人的出行

    将 activity 比作人,activity 的一次启动比作人的一次出行,ActivityRecord 就是出行记录。作如下理解

    记录ActivityRecord人出行
    身份信息info、packageName、icon姓名、性别、籍贯
    启动时基本信息launchedFromPid、task、launchedFromPackage出发地、目的地
    过程耗时记录lastVisibleTime、pauseTime步行时间、等车时间
    当前状态信息mState走路中、乘车中
    控制信息timeout、timeout 发生时的回调最多等 X 分钟车、等了 X 分钟后如何做。这里需要假定每个人的习惯都是一样的
  • 相关阅读:
    渣土车识别监测 渣土车未盖篷布识别抓拍算法
    入职面经!!!
    JAVA基础(四十四)——集合之Collection的Set接口
    Kubernetes(k8s)pod 探针检测
    Linux之history、tab、alias、命令执行顺序、管道符以及exit
    数据仓库建模实践
    408 | 【数据结构】 排序 —— 总复习框架总结
    Android Launcher3简介
    OpenShift 4 - 使用 MachineConfigPool 特性分批升级集群 Worker 节点
    设计模式:访问者模式
  • 原文地址:https://blog.csdn.net/hejnhong/article/details/127477444