什么是 ActivityRecord ?android 的解释是 An entry in the history task, representing an activity。大意是 ActivityRecord 是历史任务中的一个记录,代表着 activity,换言之,它是应用层的 activity 在 AMS 中的记录。
那么这个记录,也就是 ActivityRecord 需要记录哪些东西呢 ?
这类信息是每个 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.
是指启动 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.
在 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
这些信息好理解,也是比较重要的,记录 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 }
主要是一些过程回调的等待的 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;
(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 };
将 activity 比作人,activity 的一次启动比作人的一次出行,ActivityRecord 就是出行记录。作如下理解
| 记录 | ActivityRecord | 人出行 |
|---|---|---|
| 身份信息 | info、packageName、icon | 姓名、性别、籍贯 |
| 启动时基本信息 | launchedFromPid、task、launchedFromPackage | 出发地、目的地 |
| 过程耗时记录 | lastVisibleTime、pauseTime | 步行时间、等车时间 |
| 当前状态信息 | mState | 走路中、乘车中 |
| 控制信息 | timeout、timeout 发生时的回调 | 最多等 X 分钟车、等了 X 分钟后如何做。这里需要假定每个人的习惯都是一样的 |