VirtualApp之Activity栈

1.简介

首先是Android8.0之前系统中ActivityStack简单的关系图


VirtualApp之Activity栈_第1张图片
ActivityStack图.png
  • ActivityStackSupervisor内部有两个不同的ActivityStack对象用来管理不同的任务。mHomeStack(Stack #0)管理的是Launcher相关的任务,mFocusedStack(Stack #1)管理的是非Launcher相关的任务。

  • 一个ActivityRecord对应一个Activity,保存了一个Activity的所有信息;但是一个Activity可能会有多个ActivityRecord,因为Activity可以被多次启动,这个主要取决于其启动模式。

  • 一个TaskRecord由一个或者多个ActivityRecord组成,这就是我们常说的任务栈,具有后进先出的特点。

  • ActivityStack则是用来管理TaskRecord的,包含了多个TaskRecord。

  • Activity栈列表可通过adb指令打印 adb shell dumpsys activity

下图是通过adb打印的Activity堆栈信息,启动微信后点击home键,再启动OA

ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)
Display #0 (activities from top to bottom):
  Stack #1:
  mFullscreen=true
  mBounds=null
    Task id #6
    mFullscreen=true
    mBounds=null
    mMinWidth=-1
    mMinHeight=-1
    mLastNonFullscreenBounds=null
      TaskRecord{e869d59 #6 A=com.xdja.eoa U=0 StackId=1 sz=1}
      Intent { flg=0x10000000 cmp=com.xdja.eoa/.presenter.activity.PermissionManagerActivity }
        Hist #0: ActivityRecord{62f6659 u0 com.xdja.eoa/.presenter.activity.LoginActivity t6}
          Intent { cmp=com.xdja.eoa/.presenter.activity.LoginActivity }
          ProcessRecord{5084e39 7031:com.xdja.eoa/u0a708}
    Task id #4
    mFullscreen=true
    mBounds=null
    mMinWidth=-1
    mMinHeight=-1
    mLastNonFullscreenBounds=null
      TaskRecord{af3ad75 #4 A=com.tencent.mm U=0 StackId=1 sz=1}
      Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.tencent.mm/.ui.LauncherUI }
        Hist #0: ActivityRecord{e2e5c15 u0 com.tencent.mm/.ui.LauncherUI t4}
          Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.tencent.mm/.ui.LauncherUI bnds=[859,1644][1140,2027] }
          ProcessRecord{2743d9b 3758:com.tencent.mm/u0a868}

    Running activities (most recent first):
      TaskRecord{e869d59 #6 A=com.xdja.eoa U=0 StackId=1 sz=1}
        Run #1: ActivityRecord{62f6659 u0 com.xdja.eoa/.presenter.activity.LoginActivity t6}
      TaskRecord{af3ad75 #4 A=com.tencent.mm U=0 StackId=1 sz=1}
        Run #0: ActivityRecord{e2e5c15 u0 com.tencent.mm/.ui.LauncherUI t4}

    mResumedActivity: ActivityRecord{62f6659 u0 com.xdja.eoa/.presenter.activity.LoginActivity t6}

  Stack #0:
  mFullscreen=true
  mBounds=null
    Task id #2
    mFullscreen=true
    mBounds=null
    mMinWidth=-1
    mMinHeight=-1
    mLastNonFullscreenBounds=null
      TaskRecord{deb8c81 #2 A=com.huawei.android.launcher U=0 StackId=0 sz=1}
      Intent { act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10000300 cmp=com.huawei.android.launcher/.unihome.UniHomeLauncher }
        Hist #0: ActivityRecord{eb2db8e u0 com.huawei.android.launcher/.unihome.UniHomeLauncher t2}
          Intent { act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10000300 cmp=com.huawei.android.launcher/.unihome.UniHomeLauncher }
          ProcessRecord{90bab45 2940:com.huawei.android.launcher/u0a61}

    Running activities (most recent first):
      TaskRecord{deb8c81 #2 A=com.huawei.android.launcher U=0 StackId=0 sz=1}
        Run #0: ActivityRecord{eb2db8e u0 com.huawei.android.launcher/.unihome.UniHomeLauncher t2}

  ResumedActivity: ActivityRecord{62f6659 u0 com.xdja.eoa/.presenter.activity.LoginActivity t6}
  mFocusedStack=ActivityStack{618b10a stackId=1, 2 tasks} mLastFocusedStack=ActivityStack{618b10a stackId=1, 2 tasks}

2.系统中相关类的分析

2.1 ActivityRecord

ActivityRecord中存在着大量的成员变量,包含了一个Activity的所有信息。并通过通过成员变量task指向TaskRecord,

final class ActivityRecord extends ConfigurationContainer implements AppWindowContainerListener {

        final ActivityManagerService service; // owner
        final IApplicationToken.Stub appToken; // window manager token
        AppWindowContainerController mWindowContainerController;
        final ActivityInfo info; // activity信息
        final ApplicationInfo appInfo; // information about activity's app
        
        //省略其他成员变量

        private TaskRecord task;        // 跑在哪个Task
        //构造方法,需要传递大量信息
        ActivityRecord(ActivityManagerService _service, ProcessRecord _caller, int _launchedFromPid,
                       int _launchedFromUid, String _launchedFromPackage, Intent _intent, String _resolvedType,
                       ActivityInfo aInfo, Configuration _configuration,
                       com.android.server.am.ActivityRecord _resultTo, String _resultWho, int _reqCode,
                       boolean _componentSpecified, boolean _rootVoiceInteraction,
                       ActivityStackSupervisor supervisor, ActivityOptions options,
                       com.android.server.am.ActivityRecord sourceRecord) {
        
        }
    }

2.2.1 ActivityRecord中的Token

Token是ActivityRecord的内部静态类,我们先来看下Token的继承关系,Token extends IApplicationToken.Stub,Token是一个Binder本地对象,其他进程会拿到Token的代理端。Token标识了一个ActivityRecord对象,即间接标识了一个Activity。

VirtualApp之Activity栈_第2张图片
Token.png
  • Actvity第一次启动时,AMS会创建ActivityRecord对象,构造函数里会创建一个Token对象,保存到ActivityRecord.appToken
  • 调用WMS的addAppToken将Token对象保存到AppWindowToken.appToken
  • Activity进程启动后,AMS调用scheduleLaunchActivity将Token的代理对象保存到ActivityClientRecord.token
  • WMS调用addWindow添加窗口时会携带Token代理对象,到WMS转化成Token本地对象,判断当前添加的窗口是哪个Activity

2.2 TaskRecord

TaskRecord内部维护一个ArrayList用来保存ActivityRecord,同样,TaskRecord中的mStack表示其所在的ActivityStack。

 final class TaskRecord extends ConfigurationContainer implements TaskWindowContainerListener {
        final int taskId;       //任务ID
        final ArrayList mActivities;   //使用一个ArrayList来保存所有的ActivityRecord
        private ActivityStack mStack;   //TaskRecord所在的ActivityStack
        String affinity;    //root activity的affinity
        
        //构造方法
        TaskRecord(ActivityManagerService service, int _taskId, ActivityInfo info, Intent _intent,
                   IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor, int type) {
            
        }
        
        //添加Activity到顶部
        void addActivityToTop(com.android.server.am.ActivityRecord r) {
            addActivityAtIndex(mActivities.size(), r);
        }
        
        //添加Activity到指定的索引位置
        void addActivityAtIndex(int index, ActivityRecord r) {
            //...

            r.setTask(this);//为ActivityRecord设置TaskRecord,就是这里建立的联系
            index = Math.min(size, index);
            mActivities.add(index, r);//添加到mActivities
            
            //...
        }
    }

2.3 ActivityStack

ActivityStack内部维护了一个ArrayList用来管理TaskRecord。另外ActivityStack是由ActivityStackSupervisor来创建的,并持有ActivityStackSupervisor对象

    class ActivityStack extends ConfigurationContainer implements StackWindowListener {

        private final ArrayList mTaskHistory = new ArrayList<>();//使用一个ArrayList来保存TaskRecord
        final int mStackId;
        protected final ActivityStackSupervisor mStackSupervisor;//持有一个ActivityStackSupervisor,所有的运行中的ActivityStacks都通过它来进行管理
        
        //构造方法
        ActivityStack(ActivityStackSupervisor.ActivityDisplay display, int stackId,
                      ActivityStackSupervisor supervisor, RecentTasks recentTasks, boolean onTop) {

        }
        
        TaskRecord createTaskRecord(int taskId, ActivityInfo info, Intent intent,
                                    IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,boolean toTop, int type) {
            //创建一个task
            TaskRecord task = new TaskRecord(mService, taskId, info, intent, voiceSession, voiceInteractor, type);
            //将task添加到ActivityStack中去
            addTask(task, toTop, "createTaskRecord");
            //其他代码略
            return task;
        }
        
        //添加Task
        void addTask(final TaskRecord task, final boolean toTop, String reason) {
            addTask(task, toTop ? MAX_VALUE : 0, true /* schedulePictureInPictureModeChange */, reason);
        }

        //添加Task到指定位置
        void addTask(final TaskRecord task, int position, boolean schedulePictureInPictureModeChange,String reason) {

            mTaskHistory.remove(task);//若存在,先移除
            //...
            mTaskHistory.add(position, task);//添加task到mTaskHistory
            task.setStack(this);//为TaskRecord设置ActivityStack
            //...
        }
        //其他代码略
    }

2.4 ActivityStackSupervisor

ActivityStackSupervisor顾名思义就是用来管理ActivityStack的。内部有两个不同的ActivityStack对象,mHomeStack和mFocusedStack用来管理不同的任务。AMS初始化时会创建一个ActivityStackSupervisor对象。

    public class ActivityStackSupervisor extends ConfigurationContainer implements DisplayListener {

        ActivityStack mHomeStack;//管理的是Launcher相关的任务
        ActivityStack mFocusedStack;//管理非Launcher相关的任务
        
        //创建ActivityStack
        ActivityStack createStack(int stackId, ActivityStackSupervisor.ActivityDisplay display, boolean onTop) {
            switch (stackId) {
                case PINNED_STACK_ID:
                    //PinnedActivityStack是ActivityStack的子类
                    return new PinnedActivityStack(display, stackId, this, mRecentTasks, onTop);
                default:
                    //创建一个ActivityStack
                    return new ActivityStack(display, stackId, this, mRecentTasks, onTop);
            }
        }

    }

3.Activity启动模式

3.1 standerd

默认模式,每次启动Activity都会创建一个新的Activity实例。

比如:现在有个A Activity,我们在A上面启动B,再然后在B上面启动A,其过程如图所示:


VirtualApp之Activity栈_第3张图片
standerd.png

3.2 singleTop

如果要启动的Activity已经在栈顶,则不会重新创建Activity,只会调用该Activity的onNewIntent()方法。
如果要启动的Activity不在栈顶,则会重新创建该Activity的实例。

比如:现在有个A Activity,我们在A以standerd模式上面启动B,然后在B上面以singleTop模式启动A,其过程如图所示,这里会新创建一个A实例:

VirtualApp之Activity栈_第4张图片
image.png

如果在B上面以singleTop模式启动B的话,则不会重新创建B,只会调用onNewIntent()方法,其过程如图所示:


VirtualApp之Activity栈_第5张图片
image.png

3.3 singleTask

如果要启动的Activity已经存在于它想要归属的栈中,那么不会创建该Activity实例,将栈中位于该Activity上的所有的Activity出栈,同时该Activity的onNewIntent()方法会被调用。
如果要启动的Activity不存在于它想要归属的栈中,并且该栈存在,则会创建该Activity的实例。
如果要启动的Activity想要归属的栈不存在,则首先要创建一个新栈,然后创建该Activity实例并压入到新栈中。

比如:现在有个A Activity,我们在A以standerd模式上面启动B,然后在B上面以singleTask模式启动A,其过程如图所示:


VirtualApp之Activity栈_第6张图片
image.png

3.3.1 singleTask与onNewIntent

  • singleTask模式,每个Activity只存在一个实例,如果想再启动该Activity,那就是执行onNewIntent() -> onResart() -> onStart() -> onResume()。 如果Android系统由于内存不足把已存在Activity释放掉了,那么再次调用的时候会重新启动Activity即执行onCreate() -> onStart() -> onResume()等。
  • 当activity是同一个实例的情况下,intent发生了变化,就会进入onNewIntent中,这个方法的作用也是让你来对旧的intent进行保存,对新的intent进行对应的处理。

3.4 singleInstance

基本和singleTask一样,不同的是启动Activity时,首先要创建在一个新栈,然后创建该Activity实例并压入新栈中。
以singleInstance模式启动的Activity具有独占性,即它会独自占用一个任务,被他开启的任何activity都会运行在其他任务中

比如:现在有个A Activity,我们在A以singleInstance模式上面启动B,其过程如图所示:


VirtualApp之Activity栈_第7张图片
image.png

4 Intent中的FLAG

如果startActivity()时往Intent中加入相应的标志来指定启动模式,这种方式的优先级会比在AndroidManifest中定义的优先级高;但是AndroidManifest中只能定义四种启动方式:standard、singleTop、singleTask、singleInstance,而Intent的flag则有很多种。具体的可以看看文档

  • FLAG_ACTIVITY_NEW_TASK·:跟launchMode中的singleTask一样。
  • FLAG_ACTIVITY_SINGLE_TOP :跟launchMode中的singleTop一样。
  • FLAG_ACTIVITY_CLEAR_TOP :launchMode中没有对应的值,如果要启动的Activity已经存在于栈中,则将所有位于它上面的Activity出栈。singleTask默认具有此标记位的效果。
  • FLAG_ACTIVITY_CLEAR_TASK :任何用来放置该Activity的已经存在的task里面的已经存在的activity先清空,然后在该task中启动Activity,这个新启动的Activity变为了这个空task的根Activity。该标志必须和FLAG_ACTIVITY_NEW_TASK一起使用。
  • FLAG_ACTIVITY_MULTIPLE_TASK:不建议使用此标记,除非自己实现了应用程序的启动器。结合FLAG_ACTIVITY_NEW_TASK这个标记,即使要启动的activity已经存在一个task在运行,也会新启动一个task来运行要启动的activity
  • FLAG_ACTIVITY_REORDER_TO_FRONT:比如说原来栈中情况是A,B,C,D,在D中启动B(加入该flag),栈中的情况会是A,C,D,B.
  • FLAG_ACTIVITY_NO_ANIMATION:启动的时候不执行动画。
  • FLAG_ACTIVITY_RESET_TASK_IF_NEEDED:如果设置该属性,并且这个Activity在一个新的Task中正在被启动或者被带到一个已经存在的Task的顶部,这时这个Task会被重置(即该Task中之前的Activity会被关闭),该Activity成为栈底第一个Activity。

5 taskAffinity

taskAffinity表示当前activity具有亲和力的一个任务,设置了相同taskAffinity属性的activity,属于同一个任务。

  • Task的所有Activity只有一个taskAffinity
  • 每个Task都有affinity属性,由Task的根activity(root activity)的taskAffinity决定。
  • 默认情况下,应用中的所有activity具有相同的taskAffinity,即应用的包名。可以通过设置不同的taskAffinity属性给应用中的activity分组,也可以把不同的应用中的activity的taskAffinity设置成相同的值。

5.1 singleTask与taskAffinity的特殊处理

如果Activity中设置launchMode为SingleTask,当启动该Activity时如果Task中不存在该实例,系统会检查该Activity的taskAffinity与调用方Task的taskAffinity是否一致。如果一致,新创建的Activity实例将会放在原来的Task之上。否则系统会新建一个Task,把新创建的Activity实例作为一个根元素放在新Task之上。

例如A与B的taskAffinity属性不同,启动B时会新建一个Task

6 VirtualApp对ActivityStack的管理

6.1 Activity的启动流程

VirtualApp之Activity栈_第8张图片
startActivity流程.png
  • VA拦截了系统AMS服务,启动Activity时会调用到startActivity的Hook点(MethodProxies$startActivity)。
  • 交给VAMS进一步处理,ActivityStack用来管理VA中第三方应用的Task和Activity,并维护着第三方应用的TaskRecord和ActivityRecord列表,可以根据Activity启动模式和Intent.Flag向系统发起是否启动一个新的Task或者使用原Task,并调度Activity在堆栈中的顺序。
  • 将要启动的应用Activity的Intent封装在targetIntent中,通知系统AMS启动占坑的ShadowActivity。
  • VA拦截了“android.app.ActiivtyThread.H”回调,在HCallbackStub中处理message类型为LAUNCH_ACTIVITY的消息,从targetIntent中恢复第三方应用Activity的Intent。
  • 回到VAMS中,更新维护的TaskRecord和ActivityRecord。
  • 调用原始ActivityThread.H回调,启动第三方应用的Actvity。

6.2 系统Task与VA中Task的关系

VA在lib的AndroidManifest.xml中设置了100个占坑Activity,其中Activity属性设置android:taskAffinity="com.lody.virtual.virtual_task",对系统来说VA中启动的第三方应用的Task都属于VA,而且每个Task的taskAffinity属性相同。


VA在管理内部第三方应用Task时,会将taskAffinity重新修改成应用包名或者应用自定义的taskAffinity,便于将不同应用的Activity放在同一个Task中,系统与VA中Task的taskid是相同的。
VA中只管理了一个Stack,代表系统的Stack #1,Android9.0版本后,系统不再把所有应用的Task都放到Stack #1中,而是会根据不同应用创建很多Stack,Android 9.0中VA对栈的管理可能还存在一些问题。

VirtualApp之Activity栈_第9张图片
Task.png

6.3 VA中的ActivityStack、TaskRecord、ActivityRecord类

class ActivityStack {
    /*  [Key] = TaskId [Value] = TaskRecord  */
    private final SparseArray mHistory = new SparseArray<>();
    private final List mLaunchingActivities = new ArrayList<>();
    ...
}

class TaskRecord {
    public final List activities = new ArrayList<>();
    public int taskId;
    public int userId;
    public String affinity;
    public Intent taskRoot;
    ...
}

class ActivityRecord extends Binder {
    public TaskRecord task;
    public ActivityInfo info;
    public ComponentName component;
    public Intent intent;
    public IBinder token;
    public IBinder resultTo;
    public int userId;
    public ProcessRecord process;
    public boolean marked;
    ...
}

6.3.1 VA ActivityRecord中的token来源

private boolean handleLaunchActivity(Message msg, Object r) {
    ...
    IBinder token;
    if (BuildCompat.isPie()) {
        token = ClientTransaction.mActivityToken.get(msg.obj);
    } else {
        token = ActivityThread.ActivityClientRecord.token.get(r);
    }
    ...
}

6.4 VA对ActivityStack的详细处理流程

6.4.1 ActivityStack.startActivityLocked

假如A Activity调用ActviityStack的startActivityLocked方法启动B Activity。

int startActivityLocked(int userId, Intent intent, ActivityInfo info, IBinder resultTo, Bundle options,
                        String resultWho, int requestCode, int callingUid) {
    synchronized (mHistory) {
        //跟系统同步TaskRecord,保持VA中Task与系统中Task一致
        optimizeTasksLocked();
    }
    //根据resultTo找到A的ActivityRecord
    ActivityRecord sourceRecord = findActivityByToken(userId, resultTo);
    if (sourceRecord == null) {
        resultTo = null;
    }
    //获得B Actviity的taskAffinity属性,默认是应用包名
    String affinity = ComponentUtils.getTaskAffinity(info);
    int mLauncherFlags = 0; //启动模式
    boolean newTask = containFlags(intent, Intent.FLAG_ACTIVITY_NEW_TASK);
    boolean clearTop = containFlags(intent, Intent.FLAG_ACTIVITY_CLEAR_TOP);
    boolean clearTask = containFlags(intent, Intent.FLAG_ACTIVITY_CLEAR_TASK);
    boolean multipleTask = newTask && containFlags(intent, Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
    boolean reorderToFront = containFlags(intent, Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
    boolean singleTop = containFlags(intent, Intent.FLAG_ACTIVITY_SINGLE_TOP);
    /* FLAG_EXCLUDE_FROM_RECENTS其对应在AndroidManifest中的属性
       为android:excludeFromRecents=“true”,该Activity不出现在最近使用的列表中*/
    if ((info.flags & ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS) != 0
            || containFlags(intent, Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)) {
        mLauncherFlags |= Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
    }

    boolean notStartToFront = false;
    if (clearTop || singleTop || clearTask) {
        notStartToFront = true;
    }
    if (!newTask) {
        clearTask = false;   //clearTask使能的前提是设置newTask
    }
    TaskRecord sourceTask = null;
    if (sourceRecord != null) {
        sourceTask = sourceRecord.task;    //获得A Activity所在的Task
    }

    TaskRecord reuseTask = null;
    if (!multipleTask) {
        switch (info.launchMode) {
            case LAUNCH_SINGLE_INSTANCE: {
                //根据affinity查找VA中是否存在匹配的Task
                reuseTask = findTaskByAffinityLocked(userId, affinity);
                break;
            }
            case LAUNCH_SINGLE_TASK:
                //xdja
                if(!isAllowUseSourceTask(sourceRecord, info)){
                     break;   //sourceRecord被LAUNCH_SINGLE_INSTANCE模式启动, 需要newTask
                }
                //LAUNCH_SINGLE_TASK模式需要对比taskAffinity,如果affinity不同需要newTask
                reuseTask = findTaskByAffinityLocked(userId, affinity);
                break;

            case LAUNCH_MULTIPLE:
            case LAUNCH_SINGLE_TOP: {
                if (newTask || sourceTask == null) {
                       reuseTask = findTaskByAffinityLocked(userId, affinity);
                } else if (isAllowUseSourceTask(sourceRecord, info)) {
                       reuseTask = sourceTask;
                }
                break;
            }
            default:
                break;
        }
    }
    if (reuseTask == null || reuseTask.isFinishing()) {
        return startActivityInNewTaskLocked(mLauncherFlags, userId, intent, info, options, callingUid);
    }
    //非new Task,将查找到的sourceTask移动到前台
    mAM.moveTaskToFront(reuseTask.taskId, 0);

    /*
     * 一个APP的界面已经打开,我们按Home,再从桌面打开App,不会重新启动App的界面,
     * 而是直接仅仅把界面切到前台,匹配Task的根Activity的Intent
     */
    boolean startTaskToFront = !notStartToFront
            && ComponentUtils.intentFilterEquals(reuseTask.taskRoot, intent)
            && reuseTask.taskRoot.getFlags() == intent.getFlags();

    if (startTaskToFront) {
        return 0;
    }

    ActivityRecord notifyNewIntentActivityRecord = null;
    boolean marked = false; //标记Activity是否需要被finish掉
    ComponentName component = ComponentUtils.toComponentName(info);
    if (info.launchMode == LAUNCH_SINGLE_INSTANCE) {
        synchronized (reuseTask.activities) {
            for (ActivityRecord r : reuseTask.activities) {
                if (r.component.equals(component)) {
                    notifyNewIntentActivityRecord = r;
                    break;
                }
            }
        }
    }
    boolean notReorderToFront = false;
    if (info.launchMode == LAUNCH_SINGLE_TASK || clearTop) {
        synchronized (reuseTask.activities) {
            notReorderToFront = true;
            /*
             * (1)如果当前task包含这个Activity,这个Activity以上的Activity出栈,这个Activity到达栈顶。
             */
            int N = reuseTask.activities.size();
            while (N-- > 0) {
                ActivityRecord r = reuseTask.activities.get(N);
                if (!r.marked && r.component.equals(component)) {
                    notifyNewIntentActivityRecord = r;
                    marked = true;
                    break;
                }
            }

            if (marked) {
                while (N++ < reuseTask.activities.size() - 1) {
                   //该Activity上的所有Activity需要被标记,最后finish掉
                    reuseTask.activities.get(N).marked = true;
                }
                /*
                 *  处理 ClearTop:
                 * (2)如果这个Activity是standard模式,这个Activity也出栈,并且重新实例化到达栈顶。
                 */
                if (clearTop && info.launchMode == LAUNCH_MULTIPLE) {
                    notifyNewIntentActivityRecord.marked = true;
                    notifyNewIntentActivityRecord = null;
                }
            }
        }
    }
    if (info.launchMode == LAUNCH_SINGLE_TOP || singleTop) {
        notReorderToFront = true;
        /*
         * 打开的Activity如果在栈顶,则不创建新的实例,并且会触发onNewIntent事件。
         */
        ActivityRecord top = reuseTask.getTopActivityRecord();
        if (top != null && !top.marked && top.component.equals(component)) {
            notifyNewIntentActivityRecord = top;
        }
    }
    //假如需要重新排序到前台
    if (reorderToFront) {
        ActivityRecord top = reuseTask.getTopActivityRecord();
        if (top.component.equals(component)) {
            notifyNewIntentActivityRecord = top;
        } else {
            /*
             * 由于无法直接实现将要启动的Activity从栈中拉到栈顶,
             * 我们直接将它finish掉,并在栈顶重新启动。
             * 然而,某些Activity不能这样做(典例:网易新闻分享到微博然后点取消)
             * 好在还可以workaround之。
             */
            synchronized (reuseTask.activities) {
                int N = reuseTask.activities.size();
                while (N-- > 0) {
                    ActivityRecord r = reuseTask.activities.get(N);
                    if (r.component.equals(component)) {
                        if (notReorderToFront) {
                            notifyNewIntentActivityRecord = r;
                        } else {
                            r.marked = true;
                            marked = true;
                        }
                        break;
                    }
                }
            }
        }
    }
    if (clearTask) {
        synchronized (reuseTask.activities) {
            for (ActivityRecord r : reuseTask.activities) {
                r.marked = true;
            }
        }
        marked = true;
    }
    if (marked) {
        finishMarkedActivity();   //finish所有marked Activity
    }
    if (notifyNewIntentActivityRecord != null) {
        //调用onNewIntent
        deliverNewIntentLocked(userId, sourceRecord, notifyNewIntentActivityRecord, intent);
        if (!notifyNewIntentActivityRecord.marked) {
            return 0;
        }
    }
    ActivityRecord targetRecord = newActivityRecord(intent, info, resultTo);
    //封装intent到shadowActivity的Intent中
    Intent destIntent = startActivityProcess(userId, targetRecord, intent, info, callingUid);

    if (destIntent != null) {
        destIntent.addFlags(mLauncherFlags);    //添加启动模式
        ActivityRecord startFrom;
        if (sourceTask == reuseTask) {
            startFrom = sourceRecord;
        } else {
            startFrom = reuseTask.getTopActivityRecord(true);
        }
        //startActivity到SourceTask
        startActivityFromSourceTask(startFrom.process, startFrom.token, destIntent, resultWho, requestCode, options);
        return 0;
    } else {
        synchronized (mLaunchingActivities) {
            mLaunchingActivities.remove(targetRecord);
        }
        return -1;
    }
}

6.4.2 ActivityStack.optimizeTasksLocked

跟系统同步TaskRecord,保持VA中Task与系统中Task一致,Android9.0获取系统Task列表不全,会导致VA中误删Task。

/**
 * App started in VA may be removed in OverView screen, then AMS.removeTask
 * will be invoked, all data struct about the task in AMS are released,
 * while the client's process is still alive. So remove related data in VA
 * as well. A new TaskRecord will be recreated in `onActivityCreated`
 */
private void optimizeTasksLocked() {
    List recentTask = VirtualCore.get().getRecentTasksEx(Integer.MAX_VALUE,
            ActivityManager.RECENT_WITH_EXCLUDED | ActivityManager.RECENT_IGNORE_UNAVAILABLE);
    int N = mHistory.size();
    while (N-- > 0) {
        TaskRecord task = mHistory.valueAt(N);
        ListIterator iterator = recentTask.listIterator();
        boolean taskAlive = false;
        while (iterator.hasNext()) {
            ActivityManager.RecentTaskInfo info = iterator.next();
            if (info.id == task.taskId) {
                taskAlive = true;
                iterator.remove();
                break;
            }
        }
        if (!taskAlive) {
            mHistory.removeAt(N);
        }
    }
}

6.4.3 ActivityStack.startActivityInNewTaskLocked

启动Activity到新Task中,不需要传入resultTo,所以最后直接调用 VirtualCore.get().getContext().startActivity(destIntent);

private int startActivityInNewTaskLocked(int launcherFlags, final int userId, Intent intent, final ActivityInfo info, final Bundle options, int callingUid) {
    ActivityRecord targetRecord = newActivityRecord(intent, info, null);
    final Intent destIntent = startActivityProcess(userId, targetRecord, intent, info, callingUid);
    if (destIntent != null) {
        destIntent.addFlags(launcherFlags);
        destIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        destIntent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
        destIntent.addFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);

        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            // noinspection deprecation
            destIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
        } else {
            destIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
        }
        boolean noAnimation = false;
        try {
            noAnimation = intent.getBooleanExtra("_VA_|no_animation", false);
        } catch (Throwable e) {
            // ignore
        }
        if (noAnimation) {
            destIntent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
        }
        if (options != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            VirtualCore.get().getContext().startActivity(destIntent, options);
        } else {
            VirtualCore.get().getContext().startActivity(destIntent);
        }
        return 0;
    } else {
        mLaunchingActivities.remove(targetRecord);
        return -1;
    }

}

6.4.4 ActivityStack.startActivityFromSourceTask

启动Activity到原Task中,需要传入resultTo,通过反射调用ActivityManger的startActivity

private void startActivityFromSourceTask(ProcessRecord r, final IBinder resultTo, final Intent intent, final String resultWho,
                                         final int requestCode, final Bundle options) {
    realStartActivityLocked(r.appThread, resultTo, intent, resultWho, requestCode, options);
}

private void realStartActivityLocked(IInterface appThread, IBinder resultTo, Intent intent, String resultWho, int requestCode,
                                     Bundle options) {
    Class[] types = mirror.android.app.IActivityManager.startActivity.paramList();
    Object[] args = new Object[types.length];
    args[0] = appThread;
    int intentIndex = ArrayUtils.protoIndexOf(types, Intent.class);
    int resultToIndex = ArrayUtils.protoIndexOf(types, IBinder.class, 2);
    int optionsIndex = ArrayUtils.protoIndexOf(types, Bundle.class);
    int resolvedTypeIndex = intentIndex + 1;
    int resultWhoIndex = resultToIndex + 1;
    int requestCodeIndex = resultToIndex + 2;

    args[intentIndex] = intent;
    args[resultToIndex] = resultTo;
    args[resultWhoIndex] = resultWho;
    args[requestCodeIndex] = requestCode;
    if (optionsIndex != -1) {
        args[optionsIndex] = options;
    }
    args[resolvedTypeIndex] = intent.getType();
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
        args[intentIndex - 1] = VirtualCore.get().getHostPkg();
    }
    ClassUtils.fixArgs(types, args);

    try {
        mirror.android.app.IActivityManager.startActivity.call(ActivityManagerNative.getDefault.call(),
                (Object[]) args);
    } catch (Throwable e) {
        e.printStackTrace();
    }
}

7 生命周期

7.1 Activity生命周期

activity的四个状态running - paused - stopped - killed

  • running,当前显示在屏幕的activity(任务栈的顶部),用户可见状态。
  • paused,依旧在用户可见状态,但是界面焦点已经失去,无法与用户进行交互。
  • stopped,用户看不到当前界面,也法与用户进行交互,完全被覆盖。
  • killed,当前界面被销毁,等待这系统被回收。
VirtualApp之Activity栈_第10张图片
生命周期.png

1:启动A Activity

A Activity:onCreate()->onStart()->onResume()

2 :A Activity 启动 B Activity

A Activity:onPause()
B Activity:onCreate() -> onStart() -> onResume()
A Activity:onStop()

3:B Activity Back键返回

B Activity:onPause()
A Activity:onRestart() -> onStart() -> onResume()
B Activity:onStop() -> onDestory()

4:A Activity Home键返回

A Activity:onPause() -> onStop()

7.2 VA ActivityStack更新TaskRecord和ActivityRecord

7.2.1 onCreate

void onActivityCreated(ProcessRecord targetApp, IBinder token, int taskId, ActivityRecord record) {
    synchronized (mLaunchingActivities) {
        mLaunchingActivities.remove(record);
    }
    synchronized (mHistory) {
        optimizeTasksLocked();
        TaskRecord task = mHistory.get(taskId);
        if (task == null) {
            task = new TaskRecord(taskId, targetApp.userId, ComponentUtils.getTaskAffinity(record.info), record.intent);
            mHistory.put(taskId, task);
            Intent intent = new Intent(Constants.ACTION_NEW_TASK_CREATED);
            intent.putExtra(Constants.EXTRA_USER_HANDLE, record.userId);
            intent.putExtra(Constants.EXTRA_PACKAGE_NAME, record.info.packageName);
            VirtualCore.get().getContext().sendBroadcast(intent);
        }
        record.init(task, targetApp, token);
        synchronized (task.activities) {
            task.activities.add(record);
        }
    }
}
  • mLaunchingActivitie记录了正在启动的Activity,这时Activity已经启动完成,所以remove
  • 如果新创建了Task,将TaskRecord保存到mHistory中
  • 由于系统看到的Task的taskAffinity都是com.lody.virtual.virtual_task,在这里需要重新修改成第三方应用设置的taskAffinity
  • 发送广播告诉VA,创建了新的Task
  • 如果没有创建新Task,只是打开了Activity,将ActivityRecord保存到Task.activitys中

7.2.2 onResume

void onActivityResumed(int userId, IBinder token) {
    synchronized (mHistory) {
        optimizeTasksLocked();
        ActivityRecord r = findActivityByToken(userId, token);
        if (r != null) {
            synchronized (r.task.activities) {
                //将ActivityRecord删除后,再加入到Activity栈的栈顶
                r.task.activities.remove(r);
                r.task.activities.add(r);
            }
        }
    }
}

7.2.3 finishActivity

void onActivityFinish(int userId, IBinder token) {
    synchronized (mHistory) {
        ActivityRecord r = findActivityByToken(userId, token);
        if (r != null) {
            //标记,需要finish
            r.marked = true;
        }
    }
}

7.2.4 onDestroyed

ActivityRecord onActivityDestroyed(int userId, IBinder token) {
    synchronized (mHistory) {
        optimizeTasksLocked();
        ActivityRecord r = findActivityByToken(userId, token);
        if (r != null) {
            r.marked = true;
            synchronized (r.task.activities) {
                // We shouldn't remove task at this point,
                // it will be removed by optimizeTasksLocked().
                r.task.activities.remove(r);
            }
        }
        return r;
    }
}

7.2.5 kill app

void processDied(ProcessRecord record) {
    synchronized (mHistory) {
        optimizeTasksLocked();
        int N = mHistory.size();
        while (N-- > 0) {
            TaskRecord task = mHistory.valueAt(N);
            synchronized (task.activities) {
                Iterator iterator = task.activities.iterator();
                while (iterator.hasNext()) {
                    ActivityRecord r = iterator.next();
                    if (r.process.pid != record.pid) {
                        continue;
                    }
                    iterator.remove();
                    if (task.activities.isEmpty()) {
                        mHistory.remove(task.taskId);
                    }
                }
            }
        }
    }
}

参考

https://www.jianshu.com/p/94816e52cd77
https://blog.csdn.net/guoqifa29/article/details/46819377
https://blog.csdn.net/xiajun2356033/article/details/78741121

你可能感兴趣的:(VirtualApp之Activity栈)