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 之间的进展以及每个时间点的当时回来仓库。

Android Task的管理

使命是一个整体单元,当用户开端一个新使命或经过主屏幕按钮进入主屏幕时,使命可移至“后台”。在后台时,使命中的一切 Activity 都会中止,但使命的回来仓库会保持不变,当其他使命发动时,当时使命只是失去了焦点,如图 2 所示。这样一来,使命就能够回来到“前台”,以便用户能够从他们离开的地方继续操作。举例来说,假设当时使命(使命 A)的仓库中有 3 个 Activity,当时 Activity 下有 2 个 Activity。用户按主屏幕按钮,然后从运用发动器中发动新运用。主屏幕出现后,使命 A 转到后台。当新运用发动时,体系会发动该运用的使命(使命 B),该使命具有自己的 Activity 仓库。与该运用互动后,用户再次回来到主屏幕并挑选最初发动使命 A 的运用。现在,使命 A 进入前台,其仓库中的一切三个 Activity 都无缺如初,仓库顶部的 Activity 康复运转。此刻,用户仍可经过以下办法切换到使命 B:转到主屏幕并挑选发动该使命的运用图标。

Android Task的管理

由于回来仓库中的 Activity 不会被重新排列,假如您的运用答使用户从多个 Activity 发动特定的 Activity,体系便会创立该 Activity 的新实例并将其推送到仓库中(而不是将该 Activity 的某个先前的实例移至仓库顶部)。这样一来,运用中的一个 Activity 就可能被屡次实例化(甚至是从其他使命对其进行实例化),如图 3 所示。因而,假如用户运用回来按钮向后导航,Activity 的每个实例将依照它们被翻开的次序显现出来(每个实例都有自己的界面状况)。不过,假如您不期望某个 Activity 被实例化屡次,能够修正此行为。有关怎么完成此操作,将在后面的办理使命部分中评论。

Android Task的管理

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 中的符号来完成上述意图。

在这方面,您能够运用的首要 “ 特点包含:

  • taskAffinity
  • launchMode
  • allowTaskReparenting
  • clearTaskOnLaunch
  • alwaysRetainTaskState
  • finishOnTaskLaunch

您能够运用的首要 intent 符号包含:

  • FLAG_ACTIVITY_NEW_TASK
  • FLAG_ACTIVITY_CLEAR_TOP
  • FLAG_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);
         }  
       }  
     }
 
  } 
}

咱们发动信息运用,并经过设置按钮进入设置界面。

Android Task的管理

下面咱们经过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 #1Hist #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并没有包含嵌套其他子栈

参阅:android R版本常见dump信息分析

adb shell am stack list

5.1 Task的组织

Task在体系服务中是以树状结构组织起来的。

发动运用分屏场景,上面是相册界面,下面是微博界面

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

Android Task的管理

咱们操作只发动了Task #9、Task #11,那么Task #4、Task #5、Task #6是哪里发动的呢。这3个Task都带有 mCreatedByOrganizer=true符号,因而他们都是TaskOrganizer发动并组织起来的,而且mode=multi-window。