Android的Task管理
1. Task的概念
Android中Task是用户在执行某项工作时与之互动的一系列 Activity 的集合。系统通过任务栈来管理这些Activity,它们被按照打开的顺序进入任务栈。这些Activity可以是来自同一个App,也可以是来自不同的Apps,Activity之间不一定非得相关联。当我们按home键旁边那个方形键(recent-apps)时,屏幕上展示的就是一个个Task。
例如,电子邮件应用可能有一个 Activity 来显示新邮件列表。当用户选择一封邮件时,系统会打开一个新的 Activity 来显示该邮件。这个新的 Activity 会添加到任务栈中。如果用户按返回按钮,这个新的 Activity 会退出并从任务栈中出栈。Activity从T任务栈中出栈遵循"后进先出"的原则。
当用户点击应用图标时,该应用的任务就会转到前台运行。如果该应用没有Task(任务)存在(应用最近没有使用过),则会创建一个新的Task(任务),并且该应用的“主”Activity 将会作为任务栈的栈底 。
在当前 Activity 启动另一个 Activity 时,新的 Activity 将被推送到任务栈的顶部并获得焦点。上一个 Activity 仍保留在任务栈中,但会停止。当 Activity 停止时,系统会保留其界面的当前状态。当用户按返回按钮时,当前 Activity 会从任务栈顶部退出(该 Activity 销毁),上一个 Activity 会恢复(界面会恢复到上一个状态)。任务栈中的 Activity 永远不会重新排列,只会被送入和退出,在当前 Activity 启动时被送入任务栈,在用户使用返回按钮离开时从任务栈中退出。
因此,任务栈按照“后进先出”的对象结构运作。如下图的时间轴显示了 Activity 之间的进展以及每个时间点的当前返回堆栈。
任务是一个整体单元,当用户开始一个新任务或通过主屏幕按钮进入主屏幕时,任务可移至“后台”。在后台时,任务中的所有 Activity 都会停止,但任务的返回堆栈会保持不变,当其他任务启动时,当前任务只是失去了焦点,如图 2 所示。这样一来,任务就可以返回到“前台”,以便用户可以从他们离开的地方继续操作。举例来说,假设当前任务(任务 A)的堆栈中有 3 个 Activity,当前 Activity 下有 2 个 Activity。用户按主屏幕按钮,然后从应用启动器中启动新应用。主屏幕出现后,任务 A 转到后台。当新应用启动时,系统会启动该应用的任务(任务 B),该任务具有自己的 Activity 堆栈。与该应用互动后,用户再次返回到主屏幕并选择最初启动任务 A 的应用。现在,任务 A 进入前台,其堆栈中的所有三个 Activity 都完好如初,堆栈顶部的 Activity 恢复运行。此时,用户仍可通过以下方式切换到任务 B:转到主屏幕并选择启动该任务的应用图标。
由于返回堆栈中的 Activity 不会被重新排列,如果您的应用允许用户从多个 Activity 启动特定的 Activity,系统便会创建该 Activity 的新实例并将其推送到堆栈中(而不是将该 Activity 的某个先前的实例移至堆栈顶部)。这样一来,应用中的一个 Activity 就可能被多次实例化(甚至是从其他任务对其进行实例化),如图 3 所示。因此,如果用户使用返回按钮向后导航,Activity 的每个实例将按照它们被打开的顺序显示出来(每个实例都有自己的界面状态)。不过,如果您不希望某个 Activity 被实例化多次,可以修改此行为。有关如何实现此操作,将在后面的管理任务部分中讨论。
Activity 和任务的默认行为总结如下:
- 当 Activity A 启动 Activity B 时,Activity A 会停止,但系统会保留其状态(例如滚动位置和输入到表单中的文本)。如果用户在 Activity B 中按返回按钮,系统会恢复 Activity A 及其状态。
- 当用户通过按主屏幕按钮离开任务时,当前 Activity 会停止,其任务会转到后台。系统会保留任务中每个 Activity 的状态。如果用户稍后通过点按该任务的启动器图标来恢复该任务,该任务会进入前台并恢复堆栈顶部的 Activity。
- 如果用户按返回按钮,当前 Activity 将从堆栈中退出并销毁。堆栈中的上一个 Activity 将恢复。Activity 被销毁后,系统不会保留该 Activity 的状态。
- Activity 可以多次实例化,甚至是从其他任务对其进行实例化。
2. 管理Task
如上文所述,Android 管理任务和返回堆栈的方式是将所有接连启动的 Activity 放到同一任务和一个“后进先出”堆栈中,这对于大多数应用都很有效,而且您不必担心 Activity 如何与任务相关联,或者它们如何存在于返回堆栈中。不过,您可能需要决定是否要打破正常行为。或许您希望应用中的某个 Activity 在启动时开启一个新的任务(而不是被放入当前的任务中),或者当您启动某个 Activity 时,您希望调用它的一个现有实例(而不是在返回堆栈顶部创建一个新实例),或者您希望在用户离开任务时清除返回堆栈中除根 Activity 以外的所有 Activity。
您可以借助 [`](https://developer.android.com/guide/topics/manifest/activity-element?hl=zh-cn) 清单元素中的属性以及您传递给startActivity()` 的 intent 中的标记来实现上述目的。
在这方面,您可以使用的主要 `` 属性包括:
taskAffinitylaunchModeallowTaskReparentingclearTaskOnLaunchalwaysRetainTaskStatefinishOnTaskLaunch
您可以使用的主要 intent 标记包括:
FLAG_ACTIVITY_NEW_TASKFLAG_ACTIVITY_CLEAR_TOPFLAG_ACTIVITY_SINGLE_TOP
3. 查看Task状态
Task通过系统服务ActivityTaskManagerService来管理Task的。
$adb shell service list|grep IActivityTaskManager
5 activity_task: [android.app.IActivityTaskManager]
$adb shell dumpsys activity_task
但是activity_task无法直接dump 服务中的信息,这是因为ActivityTaskManagerService没有实现用来和dumpsys命令通信的方法。
ATMS中的信息需要借助ActivityManagerService来打印。调用流程如下:
ActiviManagerService.doDump()->ActivityTaskManagerService.dump()
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public class ActivityManagerService extends IActivityManager.Stub
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback, ActivityManagerGlobalLock {
public ActivityTaskManagerInternal mAtmInternal;
private void doDump(FileDescriptor fd, PrintWriter pw, String[] args, boolean useProto) {
......
if (opti < args.length) {
String cmd = args[opti];
opti++;
if (DUMP_ACTIVITIES_CMD.equals(cmd) || DUMP_ACTIVITIES_SHORT_CMD.equals(cmd)
|| DUMP_LASTANR_CMD.equals(cmd) || DUMP_LASTANR_TRACES_CMD.equals(cmd)
|| DUMP_STARTER_CMD.equals(cmd) || DUMP_CONTAINERS_CMD.equals(cmd)
|| DUMP_RECENTS_CMD.equals(cmd) || DUMP_RECENTS_SHORT_CMD.equals(cmd)
|| DUMP_TOP_RESUMED_ACTIVITY.equals(cmd)) {
mAtmInternal.dump(
cmd, fd, pw, args, opti, true /* dumpAll */, dumpClient, dumpPackage);
}
}
base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
public static final String DUMP_ACTIVITIES_CMD = "activities";
public static final String DUMP_ACTIVITIES_SHORT_CMD = "a";
public static final String DUMP_LASTANR_CMD = "lastanr";
public static final String DUMP_LASTANR_TRACES_CMD = "lastanr-traces";
public static final String DUMP_STARTER_CMD = "starter";
public static final String DUMP_CONTAINERS_CMD = "containers";
public static final String DUMP_RECENTS_CMD = "recents";
public static final String DUMP_RECENTS_SHORT_CMD = "r";
public static final String DUMP_TOP_RESUMED_ACTIVITY = "top-resumed";
final class LocalService extends ActivityTaskManagerInternal {
@Override
public void dump(String cmd, FileDescriptor fd, PrintWriter pw, String[] args, int opti,
boolean dumpAll, boolean dumpClient, String dumpPackage) {
pw.println("ActivityTaskManagerService dump");
synchronized (mGlobalLock) {
if (DUMP_ACTIVITIES_CMD.equals(cmd) || DUMP_ACTIVITIES_SHORT_CMD.equals(cmd)) {
dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
} else if (DUMP_LASTANR_CMD.equals(cmd)) {
dumpLastANRLocked(pw);
} else if (DUMP_LASTANR_TRACES_CMD.equals(cmd)) {
dumpLastANRTracesLocked(pw);
} else if (DUMP_STARTER_CMD.equals(cmd)) {
dumpActivityStarterLocked(pw, dumpPackage);
} else if (DUMP_CONTAINERS_CMD.equals(cmd)) {
dumpActivityContainersLocked(pw);
} else if (DUMP_RECENTS_CMD.equals(cmd) || DUMP_RECENTS_SHORT_CMD.equals(cmd)) {
if (getRecentTasks() != null) {
getRecentTasks().dump(pw, dumpAll, dumpPackage);
}
} else if (DUMP_TOP_RESUMED_ACTIVITY.equals(cmd)) {
dumpTopResumedActivityLocked(pw);
}
}
}
}
}
我们启动信息应用,并通过设置按钮进入设置界面。
下面我们通过dumpsys命令查看Task状态
$adb shell dumpsys activity a
Display #0 (activities from top to bottom):
* Task{74d84c4 #22 type=standard A=10079:com.android.messaging U=0 visible=true visibleRequested=true mode=fullscreen translucent=false sz=2}
mLastPausedActivity: ActivityRecord{184ebe1 u0 com.android.messaging/.ui.appsettings.ApplicationSettingsActivity t22}
isSleeping=false
topResumedActivity=ActivityRecord{184ebe1 u0 com.android.messaging/.ui.appsettings.ApplicationSettingsActivity t22}
* Hist #1: ActivityRecord{184ebe1 u0 com.android.messaging/.ui.appsettings.ApplicationSettingsActivity t22}
......
* Hist #0: ActivityRecord{646d67e u0 com.android.messaging/.ui.conversationlist.ConversationListActivity t22}
* Task{6c7ddbb #1 type=home ?? U=0 visible=false visibleRequested=false mode=fullscreen translucent=true sz=1}
| * Hist #0: ActivityRecord{6e7e25 u0 com.android.launcher3/.uioverrides.QuickstepLauncher t21}
* Task{dcd561e #2 type=undefined ?? U=0 visible=false visibleRequested=false mode=fullscreen translucent=true sz=0}
mCreatedByOrganizer=true
isSleeping=false
* Task{9defeff #4 type=undefined ?? U=0 visible=false visibleRequested=false mode=multi-window translucent=true sz=0}
mCreatedByOrganizer=true
isSleeping=false
* Task{dde74cc #5 type=undefined ?? U=0 visible=false visibleRequested=false mode=multi-window translucent=true sz=0}
mCreatedByOrganizer=true
isSleeping=false
3.1 设置应用的Task
设置的Task 74d84c4以standard模式启动。
topResumedActivity=ActivityRecord{184ebe1 u0 com.android.messaging/.ui.appsettings.ApplicationSettingsActivity t22}表示栈顶Activity是Resume状态,在前台显示。
Hist #1和Hist #0表示Task内部栈存在的内容。当点击返回按钮时,Task中的当前Activity(Hist #1)会出栈(Task),得到新的栈顶(Hist #0)。
3.2 桌面应用的Task
由于桌面应用没有在前台显示,因此其没有topResumeActivity. 而且其Task内部栈中只有一个元素Hist #0.
4. ActivityTaskManagerService
ActivityTaskManagerService是系统中用来管理Task的服务。
在服务侧实现IActivityTaskManager.Stub。
./base/core/java/android/app/IActivityTaskManager.aidl
/**
* System service for managing activities and their containers (task, displays,... ).
*
* {@hide}
*/
public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
public ActivityTaskManagerService(Context context) {
mContext = context;
mFactoryTest = FactoryTest.getMode();
mSystemThread = ActivityThread.currentActivityThread();
mUiContext = mSystemThread.getSystemUiContext();
mLifecycleManager = new ClientLifecycleManager();
mVisibleActivityProcessTracker = new VisibleActivityProcessTracker(this);
mInternal = new LocalService();
GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", GL_ES_VERSION_UNDEFINED);
mWindowOrganizerController = new WindowOrganizerController(this);
mTaskOrganizerController = mWindowOrganizerController.mTaskOrganizerController;
mTaskFragmentOrganizerController =
mWindowOrganizerController.mTaskFragmentOrganizerController;
mBackNavigationController = BackNavigationController.isEnabled()
? new BackNavigationController() : null;
}
public void onSystemReady() {
synchronized (mGlobalLock) {
final PackageManager pm = mContext.getPackageManager();
mHasHeavyWeightFeature = pm.hasSystemFeature(FEATURE_CANT_SAVE_STATE);
mHasLeanbackFeature = pm.hasSystemFeature(FEATURE_LEANBACK);
mVrController.onSystemReady();
mRecentTasks.onSystemReadyLocked();
mTaskSupervisor.onSystemReady();
mActivityClientController.onSystemReady();
}
}
IActivityTaskManager最重要的接口是startActivity,从startActivity开始探索。
ContextImpl.startActivity->Instrumentation.execStartActivity->ActivityTaskManager.getService().startActivity----------(服务侧)ActivityTaskManagerService.startActivity
startActivity的aidl接口定义如下
interface IActivityTaskManager {
int startActivity(in IApplicationThread caller, in String callingPackage,
in String callingFeatureId, in Intent intent, in String resolvedType,
in IBinder resultTo, in String resultWho, int requestCode,
int flags, in ProfilerInfo profilerInfo, in Bundle options);
}
第一个参数ApplicationThread将传递到ActivityTaskManager中,ApplicationThread也是一个binder对象。 系统服务可以通过这个binder对象和应用程序通信。下面是一些通信接口
base/core/java/android/app/IApplicationThread.aidl
oneway interface IApplicationThread {
void scheduleReceiver(in Intent intent, in ActivityInfo info,
in CompatibilityInfo compatInfo,
int resultCode, in String data, in Bundle extras, boolean sync,
int sendingUser, int processState);
@UnsupportedAppUsage
void scheduleCreateService(IBinder token, in ServiceInfo info,
in CompatibilityInfo compatInfo, int processState);
@UnsupportedAppUsage
void scheduleStopService(IBinder token);
void scheduleBindService(IBinder token,
in Intent intent, boolean rebind, int processState);
@UnsupportedAppUsage
void scheduleUnbindService(IBinder token,
in Intent intent);
void dispatchPackageBroadcast(int cmd, in String[] packages);
void scheduleCrash(in String msg, int typeId, in Bundle extras);
void scheduleTrimMemory(int level);
void dumpMemInfo(in ParcelFileDescriptor fd, in Debug.MemoryInfo mem, boolean checkin,
boolean dumpInfo, boolean dumpDalvik, boolean dumpSummaryOnly, boolean dumpUnreachable,
in String[] args);
void scheduleTransaction(in ClientTransaction transaction);// 非常重要
}
注意接口scheduleTransaction,这是一个非常重要的通信接口,控制生命周期就靠它了。
4.1 ApplicationThread Binder服务侧
ApplicationThread对象存在于应用侧,是ActivityThread(主线程)中的一个对象。
ase/core/java/android/app/ActivityThread.java
private class ApplicationThread extends IApplicationThread.Stub {
private static final String DB_INFO_FORMAT = " %8s %8s %14s %14s %s";
public final void scheduleReceiver(Intent intent, ActivityInfo info,
CompatibilityInfo compatInfo, int resultCode, String data, Bundle extras,
boolean sync, int sendingUser, int processState) {
updateProcessState(processState, false);
ReceiverData r = new ReceiverData(intent, resultCode, data, extras,
sync, false, mAppThread.asBinder(), sendingUser);
r.info = info;
r.compatInfo = compatInfo;
sendMessage(H.RECEIVER, r);
}
@Override
public void dumpGfxInfo(ParcelFileDescriptor pfd, String[] args) {
DumpComponentInfo data = new DumpComponentInfo();
try {
data.fd = pfd.dup();
data.token = null;
data.args = args;
sendMessage(H.DUMP_GFXINFO, data, 0, 0, true /*async*/);
} catch (IOException e) {
Slog.w(TAG, "dumpGfxInfo failed", e);
} finally {
IoUtils.closeQuietly(pfd);
}
}
public void setProcessState(int state) {
updateProcessState(state, true);
}
// 交互通信,非常重要,控制什么周期就靠它了
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
ActivityThread.this.scheduleTransaction(transaction);
}
}
通过scheduleTransaction,ATMS传递到应用ApplicationThread中的对象是ClientTransaction。
/**
* A container that holds a sequence of messages, which may be sent to a client.
* This includes a list of callbacks and a final lifecycle state.
*
* @see com.android.server.am.ClientLifecycleManager
* @see ClientTransactionItem
* @see ActivityLifecycleItem
* @hide
*/
public class ClientTransaction implements Parcelable, ObjectPoolItem {
/** A list of individual callbacks to a client. */
@UnsupportedAppUsage
private List<ClientTransactionItem> mActivityCallbacks;
/**
* Final lifecycle state in which the client activity should be after the transaction is
* executed.
*/
private ActivityLifecycleItem mLifecycleStateRequest;
/** Target client. */
private IApplicationThread mClient;
比如改变Activity的生命周期状态
public class TransactionExecutor {
public void execute(ClientTransaction transaction) {
if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Start resolving transaction");
final IBinder token = transaction.getActivityToken();
......
executeCallbacks(transaction);
executeLifecycleState(transaction);
mPendingActions.clear();
if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "End resolving transaction");
}
/** Transition to the final state if requested by the transaction. */
private void executeLifecycleState(ClientTransaction transaction) {
final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
if (lifecycleItem == null) {
// No lifecycle request, return early.
return;
}
final IBinder token = transaction.getActivityToken();
final ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
// Cycle to the state right before the final requested state.
cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */, transaction);
......
}
private void cycleToPath(ActivityClientRecord r, int finish, boolean excludeLastState,
ClientTransaction transaction) {
final int start = r.getLifecycleState();
final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState);
performLifecycleSequence(r, path, transaction);
}
/** Transition the client through previously initialized state sequence. */
private void performLifecycleSequence(ActivityClientRecord r, IntArray path,
ClientTransaction transaction) {
final int size = path.size();
for (int i = 0, state; i < size; i++) {
state = path.get(i);
switch (state) {
case ON_CREATE:
mTransactionHandler.handleLaunchActivity(r, mPendingActions,
null /* customIntent */);
break;
case ON_START:
mTransactionHandler.handleStartActivity(r, mPendingActions,
null /* activityOptions */);
break;
case ON_RESUME:
mTransactionHandler.handleResumeActivity(r, false /* finalStateRequest */,
r.isForward, "LIFECYCLER_RESUME_ACTIVITY");
break;
在ActivityThread中执行相应的Activity状态切换动作,如erformLaunchActivity、performResumeActivity等,然后走入onCreate、onResume等函数中。
5. 服务侧的Task
base/services/core/java/com/android/server/wm/Task.java
/**
* A basic container that can be used to contain activities or other {@link TaskFragment}, which
* also able to manage the activity lifecycle and updates the visibilities of the activities in it.
*/
class TaskFragment extends WindowContainer<WindowContainer> {
......
final ActivityTaskManagerService mAtmService;
final ActivityTaskSupervisor mTaskSupervisor;
final RootWindowContainer mRootWindowContainer;
private final TaskFragmentOrganizerController mTaskFragmentOrganizerController;
private ActivityRecord mPausingActivity = null;
ActivityRecord mLastPausedActivity = null;
private ActivityRecord mResumedActivity = null;
// 构建时需要一个fragmentToken
TaskFragment(ActivityTaskManagerService atmService, IBinder fragmentToken,
boolean createdByOrganizer, boolean isEmbedded) {
super(atmService.mWindowManager);
mAtmService = atmService;
mTaskSupervisor = mAtmService.mTaskSupervisor;
mRootWindowContainer = mAtmService.mRootWindowContainer;
mCreatedByOrganizer = createdByOrganizer;
mIsEmbedded = isEmbedded;
mTaskFragmentOrganizerController =
mAtmService.mWindowOrganizerController.mTaskFragmentOrganizerController;
mFragmentToken = fragmentToken;
mRemoteToken = new RemoteToken(this);
}
}
/**
* {@link Task} is a TaskFragment that can contain a group of activities to perform a certain job.
* Activities of the same task affinities usually group in the same {@link Task}. A {@link Task}
* can also be an entity that showing in the Recents Screen for a job that user interacted with.
* A {@link Task} can also contain other {@link Task}s.
*/
class Task extends TaskFragment {
String affinity; // The affinity name for this task, or null; may change identity.
String rootAffinity; // Initial base affinity, or null; does not change from initial root.
String mWindowLayoutAffinity; // Launch param affinity of this task or null. Used when saving
// launch params of this task.
/* Unique identifier for this task. */
final int mTaskId;
/* User for which this task was created. */
// TODO: Make final
int mUserId;
/**
* The TaskOrganizer which is delegated presentation of this task. If set the Task will
* emit an WindowContainerToken (allowing access to it's SurfaceControl leash) to the organizers
* taskAppeared callback, and emit a taskRemoved callback when the Task is vanished.
*/
ITaskOrganizer mTaskOrganizer;
private Task(ActivityTaskManagerService atmService, int _taskId, Intent _intent,
Intent _affinityIntent, String _affinity, String _rootAffinity,
ComponentName _realActivity, ComponentName _origActivity, boolean _rootWasReset,
boolean _autoRemoveRecents, boolean _askedCompatMode, int _userId, int _effectiveUid,
String _lastDescription, long lastTimeMoved, boolean neverRelinquishIdentity,
TaskDescription _lastTaskDescription, PersistedTaskSnapshotData _lastSnapshotData,
int taskAffiliation, int prevTaskId, int nextTaskId, int callingUid,
String callingPackage, @Nullable String callingFeatureId, int resizeMode,
boolean supportsPictureInPicture, boolean _realActivitySuspended,
boolean userSetupComplete, int minWidth, int minHeight, ActivityInfo info,
IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor,
boolean _createdByOrganizer, IBinder _launchCookie, boolean _deferTaskAppear,
boolean _removeWithTaskOrganizer) {
......
}
static Task fromWindowContainerToken(WindowContainerToken token) {
if (token == null) return null;
return fromBinder(token.asBinder()).asTask();
}
Task reuseAsLeafTask(IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor,
Intent intent, ActivityInfo info, ActivityRecord activity) {
......
}
static class Builder {
Task build() {
......
}
/** Don't use {@link Builder#buildInner()} directly. This is only used by XML parser. */
@VisibleForTesting
Task buildInner() {
return new Task(mAtmService, mTaskId, mIntent, mAffinityIntent, mAffinity,
mRootAffinity, mRealActivity, mOrigActivity, mRootWasReset, mAutoRemoveRecents,
mAskedCompatMode, mUserId, mEffectiveUid, mLastDescription, mLastTimeMoved,
mNeverRelinquishIdentity, mLastTaskDescription, mLastSnapshotData,
mTaskAffiliation, mPrevAffiliateTaskId, mNextAffiliateTaskId, mCallingUid,
mCallingPackage, mCallingFeatureId, mResizeMode, mSupportsPictureInPicture,
mRealActivitySuspended, mUserSetupComplete, mMinWidth, mMinHeight,
mActivityInfo, mVoiceSession, mVoiceInteractor, mCreatedByOrganizer,
mLaunchCookie, mDeferTaskAppear, mRemoveWithTaskOrganizer);
}
}
查询Task.Builder的构造处
ironman@ironman-VirtualBox:/mnt/data/aosp/android-13.0.0_r18/frameworks$ grep "Task.Builder" ./base/services/core/ -nrw
./base/services/core/java/com/android/server/wm/Task.java:4057: final Task task = new Task.Builder(taskSupervisor.mService)
./base/services/core/java/com/android/server/wm/Task.java:5795: task = new Task.Builder(mAtmService)
./base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java:2794: final Task task = new Task.Builder(this)
./base/services/core/java/com/android/server/wm/TaskDisplayArea.java:936: return new Task.Builder(mAtmService)
./base/services/core/java/com/android/server/wm/TaskDisplayArea.java:999: return new Task.Builder(mAtmService)
./base/services/core/java/com/android/server/wm/TaskOrganizerController.java:810: final Task task = new Task.Builder(mService)
./base/services/core/java/com/android/server/wm/RootWindowContainer.java:2009: rootTask = new Task.Builder(mService)
RootTask是什么
RootTask #:根栈的taskId,原生非分屏场景的RootTask就是Task本身,也就是RootTask并没有包含嵌套其他子栈
adb shell am stack list
5.1 Task的组织
Task在系统服务中是以树状结构组织起来的。
启动应用分屏场景,上面是相册界面,下面是微博界面
通过dumpsys window a查看Task的树状结构如下:
Display #0 (activities from top to bottom):
* Task{6b73d4e #4 type=undefined ?? U=0 displayId=0 visible=true visibleRequested=true mode=fullscreen translucent=false sz=2}
mCreatedByOrganizer=true
* Task{420d939 #6 type=undefined ?? U=0 rootTaskId=4 displayId=0 visible=true visibleRequested=true mode=multi-window translucent=false sz=1}
mBounds=Rect(0, 1209 - 1080, 2400)
mCreatedByOrganizer=true
* Task{cce5dda #11 type=undefined A=10243:com.sina.weibo U=0 rootTaskId=4 displayId=0 visible=true visibleRequested=true mode=multi-window translucent=false sz=2}
topResumedActivity=ActivityRecord{b39a9de u0 com.sina.weibo/.feed.DetailWeiboActivity} t11 d0}
* Hist #1: ActivityRecord{b39a9de u0 com.sina.weibo/.feed.DetailWeiboActivity} t11 d0}
* Hist #0: ActivityRecord{1b550bd u0 com.sina.weibo/.VisitorMainTabActivity} t11 d0}
* Task{d89c26b #5 type=undefined ?? U=0 rootTaskId=4 displayId=0 visible=true visibleRequested=true mode=multi-window translucent=false sz=1}
mBounds=Rect(0, 0 - 1080, 1191)
mCreatedByOrganizer=true
* Task{9090fe8 #9 type=standard A=10141:com.vivo.gallery U=0 rootTaskId=4 displayId=0 visible=true visibleRequested=true mode=multi-window translucent=false sz=1}
topResumedActivity=ActivityRecord{d4ce50b u0 com.vivo.gallery/com.android.gallery3d.vivo.GalleryTabActivity} t9 d0}
* Hist #0: ActivityRecord{d4ce50b u0 com.vivo.gallery/com.android.gallery3d.vivo.GalleryTabActivity} t9 d0}
* Task{8456c10 #1 type=home ?? U=0 displayId=0 visible=false visibleRequested=false mode=fullscreen translucent=true sz=1}
* Task{4e7cab #2 type=home I=com.bbk.launcher2/.Launcher U=0 rootTaskId=1 displayId=0 visible=false visibleRequested=false mode=fullscreen translucent=true sz=1}
* Hist #0: ActivityRecord{96ccd25 u0 com.bbk.launcher2/.Launcher} t2 d0}
* Task{fe5a128 #10 type=undefined A=1000:com.vivo.smartmultiwindow U=0 displayId=0 visible=false visibleRequested=false mode=fullscreen translucent=true sz=1}
isSleeping=false
* Hist #0: ActivityRecord{2e7f34b u0 com.vivo.smartmultiwindow/.minilauncher2.Launcher} t10 d0}
我们操作只启动了Task #9、Task #11,那么Task #4、Task #5、Task #6是哪里启动的呢。这3个Task都带有 mCreatedByOrganizer=true标记,因此他们都是TaskOrganizer启动并组织起来的,并且mode=multi-window。