LoginSignup
8
7

More than 1 year has passed since last update.

Android: アプリの Task と Activity Stack の状態をログに表示する

Last updated at Posted at 2022-07-30

Andorid アプリでは Activity は Task に所属し、Activity により画面遷移すると Activity の履歴が Stack に積まれています。

ActivityManager から自身のアプリが管理する Task の情報を取得することができます。自身のアプリの Task の情報をログに出力する方法を解説します。

前提

  • Android 5.0 以上であること

実装

以下の printActivityStack() Extension を実装して使用します。

/**
 * Context に所属する Task の Activity Stack をログに表示する
 */
fun Context.printActivityStack() {
    fun ComponentName.shortName(): String {
        // パッケージ名を省略してクラス名だけを取り出す
        return className.split(".").last()
    }
    val activityManager = checkNotNull(getSystemService<ActivityManager>())
    val tasks = activityManager.appTasks
    tasks.forEach { task ->
        val taskInfo = task.taskInfo
        val activitiesString = when (taskInfo.numActivities) {
            0 -> "[]"
            1 -> "[${taskInfo.baseActivity?.shortName()}]"
            2 -> "[${taskInfo.baseActivity?.shortName()} | ${taskInfo.topActivity?.shortName()}]"
            else -> "[${taskInfo.baseActivity?.shortName()} ... ${taskInfo.topActivity?.shortName()}].size = ${taskInfo.numActivities}"
        }
        val taskId = if (Build.VERSION_CODES.Q <= Build.VERSION.SDK_INT) {
            "[${taskInfo.taskId}]"
        } else ""
        Log.d("printActivityStack", "Task${taskId}: $activitiesString")
    }
}

出力

context.printActivityStack() を実行すると以下のようなログが出力されます。

Task に積まれた Activity が 1つだけのとき。

Task[12345]: [Feature1Activity]

Task に積まれた Activity が 2つだけのとき。

Task[12345]: [Feature1Activity | Feature2Activity]

Task に積まれた Activity が 3つ以上のとき。Task の最初の Activity と、最後の Activity (最前面に表示されている Activity) の情報だけが表示されます。

Task[12345]: [Feature1Activity ... Feature3Activity].size = 3

解説

ActivityManager#getAppTasks()
により、自身のアプリに所属する Task の情報を取得可能です。自身のアプリの情報であるためパーミッションは必要ありません。

AppTask#getTaskInfo()RecentTaskInfo を取り出すと、以下の情報を参照できます。

TaskInfo の情報

項目
baseActivity タスクの先頭の Activity
baseIntent タスクを起動した Intent
isRunning 起動中の Activity があるか
numActivities タスクに含まれる Activity の数
origActivity Activity Alias でタスクが起動されたときの target Activity
taskDescription Activity.setTaskDescription により設定された Task の表示名
taskId タスク ID
topActivity タスクの最後の Activity (画面表示される Activity)

Stack の情報としては baseActivity, topActivity, numActivities が該当します。先頭の Activity と末尾の Activity は取得できますが、その間にある Activity の情報は取得できません。

Tips

adb コマンドから Activity の情報を取得する

アプリから Task の Activity Stack に積まれたすべての Activity の情報を取得することはできませんが、adb コマンドを実行することで Stack 内のすべての Activity の情報を詳細に確認することが可能です。

# 以下のコマンドで ACTIVITY MANAGER ACTIVITIES を探す
# Hist #{N}: が Activity Stack 内の Activity
% adb shell dumpsys activity
...
ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)
Display #0 (activities from top to bottom):
  RootTask #27437: type=standard mode=fullscreen
  isSleeping=false
  mBounds=Rect(0, 0 - 0, 0)
  mCreatedByOrganizer=false
    mResumedActivity: ActivityRecord{1d10ba8 u0 com.android.chrome/com.google.android.apps.chrome.Main t27437}
    * Task{60c77cb #27437 type=standard A=10285:com.android.chrome U=0 visible=true mode=fullscreen translucent=false sz=1}
      mBounds=Rect(0, 0 - 0, 0)
      mMinWidth=-1 mMinHeight=-1
      userId=0 effectiveUid=u0a285 mCallingUid=u0a321 mUserSetupComplete=true mCallingPackage=com.sonymobile.launcher mCallingFeatureId=null
      affinity=10285:com.android.chrome
      intent={act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.android.chrome/com.google.android.apps.chrome.Main}
      origActivity=com.android.chrome/com.google.android.apps.chrome.Main
      mActivityComponent=com.android.chrome/org.chromium.chrome.browser.ChromeTabbedActivity
      autoRemoveRecents=false isPersistable=true activityType=1
      rootWasReset=true mNeverRelinquishIdentity=true mReuseTask=false mLockTaskAuth=LOCK_TASK_AUTH_PINNABLE
      Activities=[ActivityRecord{1d10ba8 u0 com.android.chrome/com.google.android.apps.chrome.Main t27437}]
      askedCompatMode=false inRecents=true isAvailable=true
      mRootProcess=ProcessRecord{27a429e 7746:com.android.chrome/u0a285}
      taskId=27437 rootTaskId=27437
      hasChildPipActivity=false
      mHasBeenVisible=true
      mResizeMode=RESIZE_MODE_RESIZEABLE mSupportsPictureInPicture=true isResizeable=true
      lastActiveTime=520060 (inactive for 7s)
        Hist #0: ActivityRecord{1d10ba8 u0 com.android.chrome/com.google.android.apps.chrome.Main t27437}
          Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.android.chrome/com.google.android.apps.chrome.Main bnds=[225,2237][435,2403] }
          ProcessRecord{27a429e 7746:com.android.chrome/u0a285}
...
8
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
7