背景:
前段时间学员朋友提出一个比较有意思问题,那就是假设在分屏情况下,activity进行调用startActivity进行Activity跳转,但是明显没有设置新Activity 的windowmode是mutiwindow,但是这个新的Activity为啥依旧是在分屏下展示,而且新activity的windowmode也是mutiwindow。
下面是处于一个分屏状态,点击下分屏进行activity跳转新activity依旧在分屏,这个具体源码怎么实现呢?
这个问题他不明白系统具体是怎么做的,今天马哥就针对这个学员的提问进行解答。
堆栈分析源码过程
针对这个问题的源码分析可以进行正常的源码分析,从startActivity慢慢开始追,但是这种方式效率可想而知,非常非常低,跟了马哥学习framework课程后,我相信你肯定不会选这种方法来探索啦,肯定采用是堆栈分析法。
但是这个问题应该去哪里打印堆栈呢?哪里是堆栈切入点呢?哈哈,这个就和以前课程里面分析分屏一样,可以在如下类中进行相关的堆栈添加。
对就是在这个WindowConfiguration里面的setWindowMode方法中添加堆栈,因为ActivityRecord最后的windowmode是mutilwindow,那么就肯定要调用它的setWindowMode方法哈。
启动Activity过程其实有涉及复用原来Task和新建Task两种情况,下面分别进行相关的分析。
复用task情况堆栈如下:
启动新Activity堆栈如下:
setWindowingMode:407, WindowConfiguration (android.app)
setTo:455, WindowConfiguration (android.app)
setTo:1047, Configuration (android.content.res)
onConfigurationChanged:128, ConfigurationContainer (com.android.server.wm)
onConfigurationChanged:510, WindowContainer (com.android.server.wm)
onConfigurationChanged:8487, ActivityRecord (com.android.server.wm)
onParentChanged:680, ConfigurationContainer (com.android.server.wm)
onParentChanged:586, WindowContainer (com.android.server.wm)
onParentChanged:581, WindowContainer (com.android.server.wm)
onParentChanged:1519, ActivityRecord (com.android.server.wm)
setParent:571, WindowContainer (com.android.server.wm)
addChild:745, WindowContainer (com.android.server.wm)
addChild:1835, TaskFragment (com.android.server.wm)
addChild:1429, Task (com.android.server.wm)
addOrReparentStartingActivity:2927, ActivityStarter (com.android.server.wm)
startActivityInner:1866, ActivityStarter (com.android.server.wm)
startActivityUnchecked:1661, ActivityStarter (com.android.server.wm)
executeRequest:1216, ActivityStarter (com.android.server.wm)
execute:702, ActivityStarter (com.android.server.wm)
startActivityAsUser:1240, ActivityTaskManagerService (com.android.server.wm)
startActivityAsUser:1203, ActivityTaskManagerService (com.android.server.wm)
startActivity:1178, ActivityTaskManagerService (com.android.server.wm)
onTransact:893, IActivityTaskManager$Stub (android.app)
onTransact:5183, ActivityTaskManagerService (com.android.server.wm)
execTransactInternal:1285, Binder (android.os)
execTransact:1244, Binder (android.os)
总结:
简单说就是ActivityRecord的直接Task要把ActivityRecord进行addChild,这个时候ActivityRecord是Task的Child,肯定就会吧Task的configration给ActivityRecord一遍,这个在分屏专题中其实也讲解过类似的。
新建Task的堆栈情况分析
这里大部分情况其实都是复用Task,要新建Task情况一般都是要把启动的Activity变成singleInstance
具体要在manifest中配置如下:
启动Activity后相关的堆栈打印如下:
新建Task设置windowmode堆栈情况
setWindowingMode:407, WindowConfiguration (android.app)
resolveLeafTaskOnlyOverrideConfigs:2030, Task (com.android.server.wm)
resolveOverrideConfiguration:1919, TaskFragment (com.android.server.wm)
onConfigurationChanged:127, ConfigurationContainer (com.android.server.wm)
onConfigurationChanged:510, WindowContainer (com.android.server.wm)
onConfigurationChanged:2260, TaskFragment (com.android.server.wm)
onConfigurationChangedInner:1903, Task (com.android.server.wm)
onConfigurationChanged:1976, Task (com.android.server.wm)
onParentChanged:680, ConfigurationContainer (com.android.server.wm)
onParentChanged:586, WindowContainer (com.android.server.wm)
onParentChanged:581, WindowContainer (com.android.server.wm)
onParentChanged:1171, Task (com.android.server.wm)
setParent:571, WindowContainer (com.android.server.wm)
addChild:717, WindowContainer (com.android.server.wm)
addChild:5935, Task (com.android.server.wm)
addChild:-1, Task (com.android.server.wm)
build:6548, Task
B
u
i
l
d
e
r
(
c
o
m
.
a
n
d
r
o
i
d
.
s
e
r
v
e
r
.
w
m
)
g
e
t
O
r
C
r
e
a
t
e
R
o
o
t
T
a
s
k
:
1008
,
T
a
s
k
D
i
s
p
l
a
y
A
r
e
a
(
c
o
m
.
a
n
d
r
o
i
d
.
s
e
r
v
e
r
.
w
m
)
g
e
t
O
r
C
r
e
a
t
e
R
o
o
t
T
a
s
k
:
1033
,
T
a
s
k
D
i
s
p
l
a
y
A
r
e
a
(
c
o
m
.
a
n
d
r
o
i
d
.
s
e
r
v
e
r
.
w
m
)
g
e
t
O
r
C
r
e
a
t
e
R
o
o
t
T
a
s
k
:
2839
,
R
o
o
t
W
i
n
d
o
w
C
o
n
t
a
i
n
e
r
(
c
o
m
.
a
n
d
r
o
i
d
.
s
e
r
v
e
r
.
w
m
)
g
e
t
O
r
C
r
e
a
t
e
R
o
o
t
T
a
s
k
:
3017
,
A
c
t
i
v
i
t
y
S
t
a
r
t
e
r
(
c
o
m
.
a
n
d
r
o
i
d
.
s
e
r
v
e
r
.
w
m
)
s
t
a
r
t
A
c
t
i
v
i
t
y
I
n
n
e
r
:
1858
,
A
c
t
i
v
i
t
y
S
t
a
r
t
e
r
(
c
o
m
.
a
n
d
r
o
i
d
.
s
e
r
v
e
r
.
w
m
)
s
t
a
r
t
A
c
t
i
v
i
t
y
U
n
c
h
e
c
k
e
d
:
1661
,
A
c
t
i
v
i
t
y
S
t
a
r
t
e
r
(
c
o
m
.
a
n
d
r
o
i
d
.
s
e
r
v
e
r
.
w
m
)
e
x
e
c
u
t
e
R
e
q
u
e
s
t
:
1216
,
A
c
t
i
v
i
t
y
S
t
a
r
t
e
r
(
c
o
m
.
a
n
d
r
o
i
d
.
s
e
r
v
e
r
.
w
m
)
e
x
e
c
u
t
e
:
702
,
A
c
t
i
v
i
t
y
S
t
a
r
t
e
r
(
c
o
m
.
a
n
d
r
o
i
d
.
s
e
r
v
e
r
.
w
m
)
s
t
a
r
t
A
c
t
i
v
i
t
y
A
s
U
s
e
r
:
1240
,
A
c
t
i
v
i
t
y
T
a
s
k
M
a
n
a
g
e
r
S
e
r
v
i
c
e
(
c
o
m
.
a
n
d
r
o
i
d
.
s
e
r
v
e
r
.
w
m
)
s
t
a
r
t
A
c
t
i
v
i
t
y
A
s
U
s
e
r
:
1203
,
A
c
t
i
v
i
t
y
T
a
s
k
M
a
n
a
g
e
r
S
e
r
v
i
c
e
(
c
o
m
.
a
n
d
r
o
i
d
.
s
e
r
v
e
r
.
w
m
)
s
t
a
r
t
A
c
t
i
v
i
t
y
:
1178
,
A
c
t
i
v
i
t
y
T
a
s
k
M
a
n
a
g
e
r
S
e
r
v
i
c
e
(
c
o
m
.
a
n
d
r
o
i
d
.
s
e
r
v
e
r
.
w
m
)
o
n
T
r
a
n
s
a
c
t
:
893
,
I
A
c
t
i
v
i
t
y
T
a
s
k
M
a
n
a
g
e
r
Builder (com.android.server.wm) getOrCreateRootTask:1008, TaskDisplayArea (com.android.server.wm) getOrCreateRootTask:1033, TaskDisplayArea (com.android.server.wm) getOrCreateRootTask:2839, RootWindowContainer (com.android.server.wm) getOrCreateRootTask:3017, ActivityStarter (com.android.server.wm) startActivityInner:1858, ActivityStarter (com.android.server.wm) startActivityUnchecked:1661, ActivityStarter (com.android.server.wm) executeRequest:1216, ActivityStarter (com.android.server.wm) execute:702, ActivityStarter (com.android.server.wm) startActivityAsUser:1240, ActivityTaskManagerService (com.android.server.wm) startActivityAsUser:1203, ActivityTaskManagerService (com.android.server.wm) startActivity:1178, ActivityTaskManagerService (com.android.server.wm) onTransact:893, IActivityTaskManager
Builder(com.android.server.wm)getOrCreateRootTask:1008,TaskDisplayArea(com.android.server.wm)getOrCreateRootTask:1033,TaskDisplayArea(com.android.server.wm)getOrCreateRootTask:2839,RootWindowContainer(com.android.server.wm)getOrCreateRootTask:3017,ActivityStarter(com.android.server.wm)startActivityInner:1858,ActivityStarter(com.android.server.wm)startActivityUnchecked:1661,ActivityStarter(com.android.server.wm)executeRequest:1216,ActivityStarter(com.android.server.wm)execute:702,ActivityStarter(com.android.server.wm)startActivityAsUser:1240,ActivityTaskManagerService(com.android.server.wm)startActivityAsUser:1203,ActivityTaskManagerService(com.android.server.wm)startActivity:1178,ActivityTaskManagerService(com.android.server.wm)onTransact:893,IActivityTaskManagerStub (android.app)
onTransact:5183, ActivityTaskManagerService (com.android.server.wm)
execTransactInternal:1280, Binder (android.os)
execTransact:1244, Binder (android.os)
上面就是这个Task创建变成windowmode为mutilwindow的堆栈,唯一要注意点是如下:
这里新建的task开始默认parent是TaskDisplayArea,但是这个parent会根据这个sourceTask进行变化
新建ActivityRecord的部分堆栈
setWindowingMode:407, WindowConfiguration (android.app)
setTo:455, WindowConfiguration (android.app)
setTo:1047, Configuration (android.content.res)
onConfigurationChanged:128, ConfigurationContainer (com.android.server.wm)
onConfigurationChanged:510, WindowContainer (com.android.server.wm)
onConfigurationChanged:8487, ActivityRecord (com.android.server.wm)
onParentChanged:680, ConfigurationContainer (com.android.server.wm)
onParentChanged:586, WindowContainer (com.android.server.wm)
onParentChanged:581, WindowContainer (com.android.server.wm)
onParentChanged:1519, ActivityRecord (com.android.server.wm)
setParent:571, WindowContainer (com.android.server.wm)
addChild:745, WindowContainer (com.android.server.wm)
addChild:1835, TaskFragment (com.android.server.wm)
addChild:1429, Task (com.android.server.wm)
addOrReparentStartingActivity:2927, ActivityStarter (com.android.server.wm)
setNewTask:2877, ActivityStarter (com.android.server.wm)
startActivityInner:1864, ActivityStarter (com.android.server.wm)
startActivityUnchecked:1661, ActivityStarter (com.android.server.wm)
executeRequest:1216, ActivityStarter (com.android.server.wm)
execute:702, ActivityStarter (com.android.server.wm)
startActivityAsUser:1240, ActivityTaskManagerService (com.android.server.wm)
startActivityAsUser:1203, ActivityTaskManagerService (com.android.server.wm)
startActivity:1178, ActivityTaskManagerService (com.android.server.wm)
onTransact:893, IActivityTaskManager$Stub (android.app)
onTransact:5183, ActivityTaskManagerService (com.android.server.wm)
execTransactInternal:1280, Binder (android.os)
execTransact:1244, Binder (android.os)
wms相关的层级结构树
总结图如下:
总结
1、对于ActivityRecord来说相对非常简单,就是ActivityRecord的windowmode跟着Task混就可以了,Task的WindowMode是啥就是啥
2、针对新创建的Task情况有点不一样,他们和启动这个新建Task的sourceTask有关系,如果sourceTask里面是分屏相关的task那么新建Task的的Parent就会变成和sourceTask的一样的rootTask,否则就是TaskDisplayArea即没有rootTask。
本文章更多详细代码和资料需要购买课程获取
hal+perfetto+surfaceflinger
https://mp.weixin.qq.com/s/LbVLnu1udqExHVKxd74ILg
其他课程七件套专题:
点击这里
https://mp.weixin.qq.com/s/Qv8zjgQ0CkalKmvi8tMGaw