ActivityManagerService服务可以管理系统中所有的Activity,但是AMS服务是如何管理Activity呢?
AMS中Activity的组织方式
activity组织方式.png由上图可见,Activity在AMS中组织结构为:
1:AMS中可能管理多个屏幕设备,存放在ActivityDisplays列表中
2:每个屏幕在AMS中对应一个ActivityDisplay的数据结构
3:一个屏幕中会有多个ActivityStack
4:一个ActivityStack中可能会有多个TaskRecord
5:一个TaskRecord中可能会有多个ActivityRecord
AMS中Activity相关数据结构
ActivityRecord
ActivityRecord对应一个Activity,是Activity在AMS服务中的数据结构。下面代码是ActivityRecord的一些属性。
/**
* An entry in the history stack, representing an activity.
*/
public final class ActivityRecord extends ConfigurationContainer implements
AppWindowContainerListener {
final ActivityManagerService service; // 指向AMS服务
final IApplicationToken.Stub appToken; // ActivityRecord的Token信息,和WMS中的AppWindowToken对应
AppWindowContainerController mWindowContainerController; 负责ActivityRecord和AppWindowToken之间联系
public final ActivityInfo info; // Activity相关的信息
public final ApplicationInfo appInfo; // information about activity's app
final int launchedFromPid; // 启动该Activity的Pid
final int launchedFromUid; // 启动该Activity的Uid
final String launchedFromPackage; // 哪一个package启动的这个Activity
final int userId; // Which user is this running for?
final Intent intent; // the original intent that generated us
public final String packageName; // Activity所在进程的包名
final String processName; // 此Acitivity希望运行在哪一个进程中国
final String taskAffinity; // as per ActivityInfo.taskAffinity
boolean fullscreen; // 是否是全屏Acitivity?
final boolean noDisplay; // Activity是否显示
private final boolean componentSpecified; // did caller specify an explicit component?
static final int APPLICATION_ACTIVITY_TYPE = 0;
static final int HOME_ACTIVITY_TYPE = 1;
static final int RECENTS_ACTIVITY_TYPE = 2;
static final int ASSISTANT_ACTIVITY_TYPE = 3;
int mActivityType; //Activity的类型,分为以上四种
private CharSequence nonLocalizedLabel; // Activity的label.
private int labelRes; // Activity Label资源Id
private int icon; // Icon资源Id.
private int logo; // Logo资源Id.
private int theme; // 主题资源Id.
private TaskRecord task; // 所在的TaskRecord.
private long createTime = System.currentTimeMillis(); //创建时间
long displayStartTime; // when we started launching this activity
long fullyDrawnStartTime; // when we started launching this activity
private long startTime; // last time this activity was started
long lastVisibleTime; // 最近一次visible的时间
long cpuTimeAtResume; // 在resume Activity时候 CPU的时间
long pauseTime; // 最近Pause Activity的时间
ActivityRecord resultTo; // 需要接受返回数据的那个Activity
final String resultWho; // additional identifier for use by resultTo.
final int requestCode; // code given by requester (resultTo)
ArrayList<ResultInfo> results; // pending ActivityResult objs we have received
HashSet<WeakReference<PendingIntentRecord>> pendingResults; // all pending intents for this act
ArrayList<ReferrerIntent> newIntents; // any pending new intents for single-top mode
HashSet<ConnectionRecord> connections; // All ConnectionRecord we hold //Activity中所有的连接信息
UriPermissionOwner uriPermissions; // current special URI access perms.
public ProcessRecord app; // if non-null, hosting application //所在的进程信息
boolean frontOfTask; // 是不是这个Task中的根Activity?
boolean stopped; // 是不是这个Activity Pause完成?
boolean finishing; // activity 是否在 pending finish 列表?
int launchMode; // Activity 的 launch mode 属性.
boolean visible; // 这个 activity 的 window 是否需要显示?
boolean sleeping; // 是否告诉这个Activity 进入 sleep状态?
boolean nowVisible; // is this activity's window visible?
boolean frozenBeforeDestroy;// has been frozen but not yet destroyed.
TaskRecord
TaskRecord对应Android中提到的任务栈,但什么是任务栈呢?
- android任务栈又称为Task,它是一个栈结构,具有后进先出的特性,用于存放我们的Activity组件。
- 我们每次打开一个新的Activity或者退出当前Activity都会在一个称为任务栈的结构中添加或者减少一个Activity组件,因此一个任务栈包含了一个activity的集合, android系统可以通过Task有序地管理每个activity,并决定哪个Activity与用户进行交互:只有在任务栈栈顶的activity才可以跟用户进行交互。
- 在我们退出应用程序时,必须把所有的任务栈中所有的activity清除出栈时,任务栈才会被销毁。当然任务栈也可以移动到后台, 并且保留了每一个activity的状态. 可以有序的给用户列出它们的任务, 同时也不会丢失Activity的状态信息。
- 需要注意的是,一个App中可能不止一个任务栈,某些特殊情况下,单独一个Actvity可以独享一个任务栈。还有一点就是一个Task中的Actvity可以来自不同的App,同一个App的Activity也可能不在一个Task中。
下面看下TaskRecord的实现
final class TaskRecord extends ConfigurationContainer implements TaskWindowContainerListener {
final int taskId; // Task ID.
Intent intent; // 启动这个Task的Intent信息.
long firstActiveTime; // 第一次激活Task的时间.
long lastActiveTime; // 最近一次激活的时间
boolean inRecents; // Task是否在Recent列表中?
boolean isAvailable; // Task是否可以被launch?
boolean rootWasReset; // True if the intent at the root of the task had
// the FLAG_ACTIVITY_RESET_TASK_IF_NEEDED flag.
boolean autoRemoveRecents; // If true, 当Task中Activity Finish的时候自动从Recent中移除
boolean hasBeenVisible; // Task中任何一个Activity是否对用户可见
int numFullscreen; // Task中全屏Activity的数量
int mResizeMode; // The resize mode of this task and its activities.
// Based on the {@link ActivityInfo#resizeMode} of the root activity.
private boolean mSupportsPictureInPicture; // Whether or not this task and its activities
// support PiP. Based on the {@link ActivityInfo#FLAG_SUPPORTS_PICTURE_IN_PICTURE} flag
// of the root activity. 是否支持画中画模式
private int mLockTaskMode; // Which tasklock mode to launch this task in. One of
// ActivityManager.LOCK_TASK_LAUNCH_MODE_*
final ArrayList<ActivityRecord> mActivities; //Task中所有的Activity
/** Current stack. Setter must always be used to update the value. */
private ActivityStack mStack; Task所在的ActivityStack
/** Takes on same set of values as ActivityRecord.mActivityType */
int taskType; Task类型
/** Takes on same value as first root activity */
boolean isPersistable = false;
int maxRecents;
/** Indication of what to run next when task exits. Use ActivityRecord types.
* ActivityRecord.APPLICATION_ACTIVITY_TYPE indicates to resume the task below this one in the
* task stack. */
private int mTaskToReturnTo = APPLICATION_ACTIVITY_TYPE;
// Used in the unique case where we are clearing the task in order to reuse it. In that case we
// do not want to delete the stack when the task goes empty.
private boolean mReuseTask = false;
private Bitmap mLastThumbnail; // Last thumbnail captured for this item.
private final File mLastThumbnailFile; // File containing last thumbnail.
private final String mFilename;
private TaskThumbnailInfo mLastThumbnailInfo;
CharSequence lastDescription; // Last description captured for this item.
// Whether or not this task covers the entire screen; by default tasks are fullscreen.
//是否是全屏
boolean mFullscreen = true;
// Bounds of the Task. null for fullscreen tasks.
//Task的边界
Rect mBounds = null;
private final Rect mTmpStableBounds = new Rect();
private final Rect mTmpNonDecorBounds = new Rect();
private final Rect mTmpRect = new Rect();
// Minimal width and height of this task when it's resizeable. -1 means it should use the
// default minimal width/height.
//Task缩放的最小宽高
int mMinWidth;
int mMinHeight;
//负责和WindowManagerService中 Task沟通的控制类
private TaskWindowContainerController mWindowContainerController;
ActivityStack
ActivityStack管理了一系列的TaskRecord,通过mStackId来唯一标识,持有ActivityStackSupervisor的引用。
ActivityStack的种类一共有5种
frameworks/base/core/java/android/app/ActivityManager.java
public static class StackId {
/** Invalid stack ID. */
public static final int INVALID_STACK_ID = -1;
/** First static stack ID. */
public static final int FIRST_STATIC_STACK_ID = 0;
/** Home activity stack ID. */
public static final int HOME_STACK_ID = FIRST_STATIC_STACK_ID;
/** ID of stack where fullscreen activities are normally launched into. */
public static final int FULLSCREEN_WORKSPACE_STACK_ID = 1;
/** ID of stack where freeform/resized activities are normally launched into. */
public static final int FREEFORM_WORKSPACE_STACK_ID = FULLSCREEN_WORKSPACE_STACK_ID + 1;
/** ID of stack that occupies a dedicated region of the screen. */
public static final int DOCKED_STACK_ID = FREEFORM_WORKSPACE_STACK_ID + 1;
/** ID of stack that always on top (always visible) when it exist. */
public static final int PINNED_STACK_ID = DOCKED_STACK_ID + 1;
/** Last static stack stack ID. */
public static final int LAST_STATIC_STACK_ID = PINNED_STACK_ID;
...
}
-
HOME STACK
HOME_STACK_ID标识的ActivityStack主要维护了launcheractivity和recentactivity所在的TaskRecord -
FREEFORM STACK
FREEFORM_WORKSPACE_STACK_ID标识的ActivityStack主要维护了FREEFORM模式下的TaskRecord -
DOCKED STACK
分屏的应用进入分屏模式后会在DOCKED_STACK_ID标识的ActivityStack中 -
PINNED STACK
进入画中画模式之后会在PINNED_STACK_ID标识的ActivityStack中。 -
FULLSCREEN STACK
一般情况下,我们接触到的绝大部分都是在FULLSCREEN_WORKSPACE_STACK_ID(全屏显示)标识的ActivityStack中。
ActivityStack并不是开机就创建的,而是在需要时才创建。
以下的ActivityStack的实现
/**
* State and management of a single stack of activities.
*/
class ActivityStack<T extends StackWindowController> extends ConfigurationContainer
implements StackWindowListener {
// Ticks during which we check progress while waiting for an app to launch.
static final int LAUNCH_TICK = 500;
//Activity Pause 超时时间
// How long we wait until giving up on the last activity to pause. This
// is short because it directly impacts the responsiveness of starting the
// next activity.
private static final int PAUSE_TIMEOUT = 500;
//Activity STOP超时时间
// How long we wait for the activity to tell us it has stopped before
// giving up. This is a good amount of time because we really need this
// from the application in order to get its saved state.
private static final int STOP_TIMEOUT = 10 * 1000;
//是否显示Starting Window
// Set to false to disable the preview that is shown while a new activity
// is being started.
private static final boolean SHOW_APP_STARTING_PREVIEW = true;
//Activity 的状态
enum ActivityState {
INITIALIZING,
RESUMED,
PAUSING,
PAUSED,
STOPPING,
STOPPED,
FINISHING,
DESTROYING,
DESTROYED
}
// Stack 不是显示状态.
static final int STACK_INVISIBLE = 0;
// Stack 处于显示状态
static final int STACK_VISIBLE = 1;
//AMS服务
final ActivityManagerService mService;
//WMS服务
private final WindowManagerService mWindowManager;
//和WMS服务中TaskStack沟通的控制类
T mWindowContainerController;
//Recent Task
private final RecentTasks mRecentTasks;
//该Stack中所有的TaskRecord
private final ArrayList<TaskRecord> mTaskHistory = new ArrayList<>();
/**
* List of running activities, sorted by recent usage.
* The first entry in the list is the least recently used.
* It contains HistoryRecord objects.
*/
final ArrayList<ActivityRecord> mLRUActivities = new ArrayList<>();
/**
* Animations that for the current transition have requested not to
* be considered for the transition animation.
*/
final ArrayList<ActivityRecord> mNoAnimActivities = new ArrayList<>();
/**
*当前正处于Pausing状态的Activity
* When we are in the process of pausing an activity, before starting the
* next one, this variable holds the activity that is currently being paused.
*/
ActivityRecord mPausingActivity = null;
/**
* 上一次Pause的Activity
* This is the last activity that we put into the paused state. This is
* used to determine if we need to do an activity transition while sleeping,
* when we normally hold the top activity paused.
*/
ActivityRecord mLastPausedActivity = null;
/**
* 当前处于resume状态的Activity
* Current activity that is resumed, or null if there is none.
*/
ActivityRecord mResumedActivity = null;
//Stack是否是全屏的,默认的Stack是全屏Stack
// Whether or not this stack covers the entire screen; by default stacks are fullscreen
boolean mFullscreen = true;
// 当前Stack的大小,全屏的话默认为Null
// Current bounds of the stack or null if fullscreen.
Rect mBounds = null;
// Stack ID
final int mStackId;
/** The other stacks, in order, on the attached display. Updated at attach/detach time. */
// TODO: This list doesn't belong here...
// 其他的Stack
ArrayList<ActivityStack> mStacks;
//Stack所在Display的 ID
/** The attached Display's unique identifier, or -1 if detached */
int mDisplayId;
/** Run all ActivityStacks through this */
//负责管理所有的Stack
protected final ActivityStackSupervisor mStackSupervisor;
ActivityDisplay
Activity Display代表一个物理屏幕,mStacks是该屏幕上所有的ActivityStack
class ActivityDisplay extends ConfigurationContainer {
/** Actual Display this object tracks. */
int mDisplayId; //DisplayId
Display mDisplay;
//该屏幕上的所有ActivityStack
/** All of the stacks on this display. Order matters, topmost stack is in front of all other
* stacks, bottommost behind. Accessed directly by ActivityManager package classes */
final ArrayList<ActivityStack> mStacks = new ArrayList<>();
//在创建的将Display放入mActivityDisplays列表中
ActivityDisplay() {
mActivityDisplays.put(mDisplayId, this);
}
ActivityDisplays
ActivityDisplays是Activity Display的列表,存放了当前所有的屏幕信息。可能会有多个屏幕同时存在。
在ActivityDisplay创建的时候就默认放入了activityDisplay列表中。
private final SparseArray<ActivityDisplay> mActivityDisplays = new SparseArray<>();
网友评论