安卓分屏下Activity启动其他Activity为啥也在分屏下?-framework深入剖析

31 篇文章 18 订阅

背景:

前段时间学员朋友提出一个比较有意思问题,那就是假设在分屏情况下,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

视频试看:
https://www.bilibili.com/video/BV1wc41117L4/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千里马学框架

帮助你了,就请我喝杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值