赞
踩
本文先解决以下疑问,然后给出分屏的总体结构
a. 分屏task 哪里来
b. 分屏task 信息如何同步到Systemui
c. 如何进入分屏并显示分屏的操作view
第三个:
11-12 08:27:40.037 2408 3213 E DEBUGTASKOR: Createtask 3 windowingMode = 6com.android.wm.shell.ShellTaskOrganizer.createRootTask:58 com.android.wm.shell.splitscreen.StageTaskListener.:30 com.android.wm.shell.splitscreen.SideStage.:0 com.android.wm.shell.splitscreen.StageCoordinator.:20 com.android.wm.shell.ShellInitImplKaTeX parse error: Can't use function '$' in math mode at position 103: …l.ShellInitImpl$̲InitImplExternalSyntheticLambda0.run:83 com.android.systemui.SystemUIApplicationKaTeX parse error: Can't use function '$' in math mode at position 243: …l.ShellInitImpl$̲InitImpl.init:9…ExternalSyntheticLambda7.onContextAvailable:7 com.android.systemui.keyguard.KeyguardSliceProvider.onCreateSliceProvider:6 androidx.slice.SliceProvider.onCreate:0 android.content.ContentProvider.attachInfo:2451
从堆栈我们就能看出一个简单的结构:
Systemui 初始化shell的时候会创建StageCoordinator
以及内部有两个SideStage 和MainStage
虽然还没看,但可以大胆猜想一下,其实这里StageCoordinator常见的是分屏的根SideStage 和MainStage分别创建了两个容纳两个应用的task,那么我猜测StageCoordinator 从名字以及创建的位置可以确定他是决定分屏两个task的位置大小层级的。
SideStage 和 MainStage不用说 就是分屏的主次task app状态维护的了。
好我们现在主角出现了四个(顺便提一句 StageCoordinator依附SplitScreenController ,SplitScreenController 有wmshell中WMShellModule.java 对sysmeui提供)
ShellTaskOrganizer StageCoordinator SideStage MainStage
ShellTaskOrganizer 没啥好说的BP的封装,以及APP 注入信息回调等,可以理解为 两进城的信息传递桥梁。 当然我们这里只是关注BP部分,这里面还有个BN其实 主要是systemui这边为了监听system测task信息变化,属于下一个问题,一会再说。
来看看 StageCoordinator, 他的创建在SplitScreenController
Java
public void onOrganizerRegistered() {
if (mStageCoordinator == null) {
// TODO: Multi-display
mStageCoordinator = new StageCoordinator(mContext, DEFAULT_DISPLAY, mSyncQueue,
mTaskOrganizer, mDisplayController, mDisplayImeController,
mDisplayInsetsController, mTransitions, mTransactionPool, mLogger,
mIconProvider, mMainExecutor, mRecentTasksOptional, mUnfoldControllerProvider);
}
}
SplitScreenController 属于ShellInitImpl 一部分,并跟随ShellInitImpl 初始化
看一下StageCoordinator 初始化的时候做了啥
Java
StageCoordinator(Context context, int displayId, SyncTransactionQueue syncQueue,
ShellTaskOrganizer taskOrganizer, DisplayController displayController,
DisplayImeController displayImeController,
DisplayInsetsController displayInsetsController, Transitions transitions,
TransactionPool transactionPool, SplitscreenEventLogger logger,
IconProvider iconProvider, ShellExecutor mainExecutor,
Optional recentTasks,
Provider<Optional> unfoldControllerProvider) {
mContext = context;
mDisplayId = displayId;
mSyncQueue = syncQueue;
mTaskOrganizer = taskOrganizer;
mLogger = logger;
mMainExecutor = mainExecutor;
mRecentTasks = recentTasks;
mMainUnfoldController = unfoldControllerProvider.get().orElse(null);
mSideUnfoldController = unfoldControllerProvider.get().orElse(null);
创建分屏的主task
taskOrganizer.createRootTask(displayId, WINDOWING_MODE_FULLSCREEN, this /* listener */);
mMainStage = new MainStage( mContext, mTaskOrganizer, mDisplayId, mMainStageListener, mSyncQueue, mSurfaceSession, iconProvider, mMainUnfoldController); mSideStage = new SideStage( mContext, mTaskOrganizer, mDisplayId, mSideStageListener, mSyncQueue, mSurfaceSession, iconProvider, mSideUnfoldController); mDisplayController = displayController; mDisplayImeController = displayImeController; mDisplayInsetsController = displayInsetsController; mTransactionPool = transactionPool; final DeviceStateManager deviceStateManager = mContext.getSystemService(DeviceStateManager.class); deviceSt
可以看到 主要创建了一个分屏的主task,这下面会挂两个主次分屏应用
另外这里还有个private SplitLayout mSplitLayout; 这个可能和分屏bar有关,后面看分屏view 操作的时候看。
主次分屏主要处理类为这里创建的mMainStage 和 mSideStage
再分别看看mMainStage 和 mSideStage
这两个类构造函数都是创建了各自装自己app的task
Java
StageTaskListener(Context context, ShellTaskOrganizer taskOrganizer, int displayId,
StageListenerCallbacks callbacks, SyncTransactionQueue syncQueue,
SurfaceSession surfaceSession, IconProvider iconProvider,
@Nullable StageTaskUnfoldController stageTaskUnfoldController) {
mContext = context;
mCallbacks = callbacks;
mSyncQueue = syncQueue;
mSurfaceSession = surfaceSession;
mIconProvider = iconProvider;
mStageTaskUnfoldController = stageTaskUnfoldController;
taskOrganizer.createRootTask(displayId, WINDOWING_MODE_MULTI_WINDOW, this);
}
现在分屏的主体结构有了。看一下到目前为止systemui这边 或者说wmshell的整体结构吧
到此view 出现了。
后续view 至于怎么加入的,有兴趣自己看就不看了。
不知道你注意到没,要想走到这里还有一至关重要的条件就是mMainStage.isActive()
好再看一下mMainStage 的状态。
这个是在startTasks 时候将mMainStage设置为active的。
如果走的系统直接reparent 就直接走onStageHasChildrenChanged 这条路径。有兴趣自己跟一下流程。
好了就完事了。
我这个也是第一次看,但是我基本觉得我可以搞分屏开发了,就看各位看了了解了几分吧
目前已经成功用此框架完成新功能开发
里面也许有些许错误 毕竟第一次看 只看了不到两天哈 见谅。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。