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}
...