扒扒Task与Activity启动模式

最近在重新整理Activity的启动模式,顺便也扒了扒任务栈Task,接着又去了解了下Android的概览屏幕,把页面间的跳转、任务栈存放与管理及从任务列表窗口恢复,整体串通的了解了一下。下面有几个基本的问题,你不妨测试一下,看看能掌握多少?

发自灵魂的拷问

  • 设置启动模式为singleTask,若栈内已有该实例,是否栈内就一定是复用的,不会创建实例?
  • 若Intent设置FLAG_ACTIVITY_NEW_TASK,任何启动模式,如果采取startActivityForResult()启动Activity,onActivityResult()有何变化?
  • LauncherActivity->A(standard)->B(singleInstance)按下home键,点击桌面app图标,会发生什么?
  • LauncherActivity->A(standard)->B(standard)->C(singleInstance)->A,按下返回键,会发生什么?
  • 当调用startActivityForResult启动Activity,那么启动模式会发生什么变化?
下面我就带着大家一块测试和分析一下,本篇博客测试设备Pixel(API19)、小米(API21)和OPPO(API27),主要是把android系统5.0作为一个分水岭来测试,因为官方的文档很多地方未交代清楚,需要考证。 ## ActivityRecord、TaskRecord和ActivityStack 先来扒扒这三者的关系,可以更加方便的让我们去理解启动模式。 `ActivityRecord`可以说是在任务栈中记录或保存Activity信息的实体类,它对应一个Activity,但是同一个Activity可以对应多个ActivityRecord,因为Activity可以多次被启动实例化,由启动模式、taskAffinity和FLAG决定的。
/** 【注意:此处源码的解释】
 * An entry in the history stack, representing an activity.
 */
final class ActivityRecord extends ConfigurationContainer implements AppWindowContainerListener {
  ApplicationInfo appInfo; // information about activity's app
    final int launchedFromPid; // always the pid who started the activity.
    final int launchedFromUid; // always the uid who started the activity.
    final String launchedFromPackage; // always the package who started the activity.
    final int userId;          // Which user is this running for?
    final Intent intent;    // the original intent that generated us
    final ComponentName realActivity;  // the intent component, or target of an alias.
    final String shortComponentName; // the short component name of the intent
    final String resolvedType; // as per original caller;
    final String packageName; // the package implementing intent's component
    final String processName; // process where this component wants to run
    final String taskAffinity; // as per ActivityInfo.taskAffinity
   ......部分省略
}

TaskRecord表示任务栈,记录着Activity开启的先后顺序,特点是先进后出,一系列相同的ActivityRecord保存在一个TaskRecord中,他们的TaskId是相同的,也就是说TaskRecord是由一个或者多个ActivityRecord所组成,简单看下字段

class TaskRecord extends ConfigurationContainer implements TaskWindowContainerListener {
    final int taskId;       // Unique identifier for this task.
    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.
    final IVoiceInteractionSession voiceSession;    // Voice interaction session driving task
    final IVoiceInteractor voiceInteractor;         // Associated interactor to provide to app
    Intent intent;          // The original intent that started the task. Note that this value can
                            // be null.
    Intent affinityIntent;  // Intent of affinity-moved activity that started this task.
    int effectiveUid;       // The current effective uid of the identity of this task.
    ComponentName origActivity; // The non-alias activity component of the intent.
    ComponentName realActivity; // The actual activity component that started the task.
    boolean realActivitySuspended; // True if the actual activity component that started the
                                   // task is suspended.
    boolean inRecents;      // Actually in the recents list?
    long lastActiveTime;    // Last time this task was active in the current device session,
    ......部分省略
}

ActivityStack则是用来管理TaskRecord的,里面包含多个TaskRecord,用源码的解释就是一个栈所有活动界面(TaskRecord中)的状态和管理

/**【注意:此处源码的解释】
 * State and management of a single stack of activities.
 */
class ActivityStack<T extends StackWindowController> extends ConfigurationContainer implements StackWindowListener {
 enum ActivityState {
        INITIALIZING,
        RESUMED,
        PAUSING,
        PAUSED,
        STOPPING,
        STOPPED,
        FINISHING,
        DESTROYING,
        DESTROYED
    }
    ......部分省略
 /**
     * The back history of all previous (and possibly still
     * running) activities.  It contains #TaskRecord objects.
     */
    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<>();
    /**
     * 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;
    /**
     * 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;
    ......部分省略
}

简单的举个栗子:从系统桌面开

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值