1.简介
首先是Android8.0之前系统中ActivityStack简单的关系图
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。
- 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
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
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,其过程如图所示:
3.2 singleTop
如果要启动的Activity已经在栈顶,则不会重新创建Activity,只会调用该Activity的onNewIntent()方法。
如果要启动的Activity不在栈顶,则会重新创建该Activity的实例。
比如:现在有个A Activity,我们在A以standerd模式上面启动B,然后在B上面以singleTop模式启动A,其过程如图所示,这里会新创建一个A实例:
如果在B上面以singleTop模式启动B的话,则不会重新创建B,只会调用onNewIntent()方法,其过程如图所示:
3.3 singleTask
如果要启动的Activity已经存在于它想要归属的栈中,那么不会创建该Activity实例,将栈中位于该Activity上的所有的Activity出栈,同时该Activity的onNewIntent()方法会被调用。
如果要启动的Activity不存在于它想要归属的栈中,并且该栈存在,则会创建该Activity的实例。
如果要启动的Activity想要归属的栈不存在,则首先要创建一个新栈,然后创建该Activity实例并压入到新栈中。
比如:现在有个A Activity,我们在A以standerd模式上面启动B,然后在B上面以singleTask模式启动A,其过程如图所示:
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,其过程如图所示:
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的启动流程
- 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对栈的管理可能还存在一些问题。
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,当前界面被销毁,等待这系统被回收。
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