您的位置:首页 > 财经 > 产业 > 网上开店卖货流程_深圳形象设计公司_今日小说排行榜百度搜索风云榜_今日头条官网首页

网上开店卖货流程_深圳形象设计公司_今日小说排行榜百度搜索风云榜_今日头条官网首页

2025/7/14 1:13:23 来源:https://blog.csdn.net/qq_18420641/article/details/146185654  浏览:    关键词:网上开店卖货流程_深圳形象设计公司_今日小说排行榜百度搜索风云榜_今日头条官网首页
网上开店卖货流程_深圳形象设计公司_今日小说排行榜百度搜索风云榜_今日头条官网首页

简介:

我们在对fw 原生的Task定制的时候,难免会出现各种黑屏的问题,如上图所示中间区域显示区域没有任何可见的view,然而我们来看看他的WindowManagerTrace 和 SurfaceFlingerTrace 

WindowManagerTrace

SurfaceFlingerTrace

这里能看出来是因为父亲不可见导致的,我们再来看看父亲(Task)

根据我们抓取的相关窗口信息,可以得出以下结论:上层窗口明明可以看到,但在 SurfaceFlinger 层却不可见。这是为什么呢?

有经验的同学们应该知道,无论是 AMS 还是 WMS,都只是框架(fw)为应用封装的一套规则,真正的核心在于 SurfaceControl。它与底层的 SurfaceComposerClient 直接交互,控制着图层 Layer 的各种显示和隐藏状态。换句话说,WindowManagerTrace 抓取的只是客户端的上层表象,而真正的显示与否则由 SurfaceFlingerTrace 决定。我们大胆猜测,可能是这个 Task 的某个地方直接设置了 SurfaceControl 的状态,但没有通知 WindowManagerTrace,导致了显示上的差异。

通过对SurfaceFlingerTrace的我们能知道,桌面黑屏是因为Launcher的MainActivity不可见了,不可见的原因是 Hidden by parent Task=1,然而Task1不可见的原因是 Flag is hidden是隐藏状态,所以Task1处于隐藏中,所以我们要知道这个 Flag is hidden是怎么被设置的,fw所有的对窗口的操作,最终都会执行到SurfaceControl做最后的提交,我们看看SurfaceControl 中有那些方法控制着一个图层的隐藏

我们能发现在这三个地方控制这图层的隐藏,然后我们在这几个地方加上日志,复现问题或者加上堆栈的打印,我们就能知道是谁调用的隐藏,在进行反推看看,为什么被执行了隐藏,然而我可以很遗憾的告诉大家,在进行调试验证,问题复现时,这三个最直接的地方并没有被调用,对没错并没有调用,就那么水灵灵的在我眼前一下黑屏了!分析到这里一下就断了线索,一整懵逼不知道下一步又该怎么分析,(当然大家在对底层熟悉的可以继续往底层的Layer加日志调试堆栈CallStack callStack(mLogTag);)经过很久的...................................................................

再次分析SurfaceFlingerTrace

我们在回去SurfaceFlingerTrace的进行分析,我右发现了其他的怀疑点,我们先看看还没有黑屏的时候的Task1的状态

Task=1#68 ,在看异常的时候的

Task=1#188 ,task从68变成了188,恍然大悟,68变成了188 意味着Task被重新挂载了。继续打断点追踪

通过堆栈我们能看出来,Task =1进行了reparent,首先我们就会有一个疑问,执行了reparent就会导致Task的不可见吗? ,显然这并不能直接证明这是导致问题的直接原因,所以我们就需要对当前的这整个执行流程做详细的梳理

根据堆栈,我们来看到TaskOrganizerController--->registerTaskOrganizer

我们来看看这块都在做什么。这个方法时TaskOrganizerController中的registerTaskOrganizer注册任务组织者的实现,那什么是TaskOrganizer,这是fw中为了管理各个task的一个功能,比如在ShellTaskOrganizer extends TaskOrganizer 就是继承了TaskOrganizer,并且注册了registerOrganizer()

通过registerOrganizer最终会一步步的执行到TaskOrganizerController中的registerTaskOrganizer注册,后续就能监听到所有Task的变化,如registerTaskOrganizer(ITaskOrganizer organizer)中的接口定义

没错,就是接口中每个方法的英文的意思,这样就能监听到所有task的状态变化,来实现自己的相关业务,我们接着分段看TaskOrganizerController中的registerTaskOrganizer()

代码解读:

  1. 取出远端的Binder uid origId这样就知道是那个进程在注册
  2. 创建出一个集合taskInfos保存着当前被组织的TaskAppearedInfo信息,后面我们会讲解到这个集合
  3. withGlobalLock 在一个线程中去执行我们的任务
  4. 首先,检查当前注册的组织者是否已存在于 mTaskOrganizerStates 集合中。如果不存在,则将其添加到 mTaskOrganizers 和 mTaskOrganizerStates 两个集合中。这一步骤保证了仅有唯一的组织者参与任务管理,同时向其他模块提供当前任务组织者的信息。
  5. mTaskOrganizerStates集合用organizer的Binder作为key,同时创建一个TaskOrganizerState对象记录者当前的组织者管理的所有的任务

  1. 通过前面创建的organizer.asBinder获取一个TaskOrganizerState
  2. 通过ActivityTaskManagerService拿到mRootWindowContainer循环遍历所有的Task
  3. 获取当前task的mCreatedByOrganizer,表示当前的task的创建是否是组织者创建的
  4. 循环遍历所有的task ,并且跟新他们的Organizer,task.updateTaskOrganizerState(returnTask /* skipTaskAppeared */);
  5. 经过if判断后会创建一个TaskAppearedInfo保存在taskInfos,return并且返回

经过上面的堆栈,我们知道是通过updateTaskOrganizerState触发的重新reparent,

    boolean updateTaskOrganizerState(boolean skipTaskAppeared) {if (getSurfaceControl() == null) {// Can't call onTaskAppeared without a surfacecontrol, so defer this until next one// is created.return false;}if (!canBeOrganized()) {return setTaskOrganizer(null);}final TaskOrganizerController controller = mWmService.mAtmService.mTaskOrganizerController;final ITaskOrganizer organizer = controller.getTaskOrganizer();// Do not change to different organizer if the task is created by organizer because only// the creator knows how to manage it.if (mCreatedByOrganizer && mTaskOrganizer != null && organizer != null&& mTaskOrganizer != organizer) {return false;}return setTaskOrganizer(organizer, skipTaskAppeared);}

经过一些状态的判断继续执行setTaskOrganizer

@VisibleForTestingboolean setTaskOrganizer(ITaskOrganizer organizer, boolean skipTaskAppeared) {if (mTaskOrganizer == organizer) {return false;}ITaskOrganizer prevOrganizer = mTaskOrganizer;// Update the new task organizer before calling sendTaskVanished since it could result in// a new SurfaceControl getting created that would notify the old organizer about it.mTaskOrganizer = organizer;// Let the old organizer know it has lost control.sendTaskVanished(prevOrganizer);if (mTaskOrganizer != null) {if (!skipTaskAppeared) {sendTaskAppeared();}} else {// No longer managed by any organizer.final TaskDisplayArea taskDisplayArea = getDisplayArea();if (taskDisplayArea != null) {taskDisplayArea.removeLaunchRootTask(this);}setForceHidden(FLAG_FORCE_HIDDEN_FOR_TASK_ORG, false /* set */);if (mCreatedByOrganizer) {removeImmediately("setTaskOrganizer");}}return true;}

这个地方需要注意,方法中我们传入了一个组织者organizer,并且把之前的mTaskOrganizer赋值给prevOrganizer,需要把之前的组织者全部数据清除sendTaskVanished(prevOrganizer);

    private void sendTaskVanished(ITaskOrganizer organizer) {if (organizer != null) {mAtmService.mTaskOrganizerController.onTaskVanished(organizer, this);}}
 void onTaskVanished(ITaskOrganizer organizer, Task task) {final TaskOrganizerState state = mTaskOrganizerStates.get(organizer.asBinder());if (state != null && state.removeTask(task, task.mRemoveWithTaskOrganizer)) {onTaskVanishedInternal(state, task);}}

如果state不为null ,就需要移除执行state.removeTask(task, task.mRemoveWithTaskOrganizer))

   private boolean removeTask(Task t, boolean removeFromSystem) {mOrganizedTasks.remove(t);mInterceptBackPressedOnRootTasks.remove(t.mTaskId);boolean taskAppearedSent = t.mTaskAppearedSent;if (taskAppearedSent) {if (t.getSurfaceControl() != null) {t.migrateToNewSurfaceControl(t.getPendingTransaction());}t.mTaskAppearedSent = false;}if (removeFromSystem) {mService.removeTask(t.mTaskId);}return taskAppearedSent;}

根据堆栈的调用会调用各自task的migrateToNewSurfaceControl()挂载到新的SurfaceControl

    @Overridevoid migrateToNewSurfaceControl(SurfaceControl.Transaction t) {super.migrateToNewSurfaceControl(t);mLastSurfaceSize.x = 0;mLastSurfaceSize.y = 0;updateSurfaceSize(t);}
  void migrateToNewSurfaceControl(SurfaceControl.Transaction t) {t.remove(mSurfaceControl);// Clear the last position so the new SurfaceControl will get correct positionmLastSurfacePosition.set(0, 0);mLastDeltaRotation = Surface.ROTATION_0;final Builder b = mWmService.makeSurfaceBuilder(null).setContainerLayer().setName(getName());setInitialSurfaceControlProperties(b);// If parent is null, the layer should be placed offscreen so reparent to null. Otherwise,// set to the available parent.t.reparent(mSurfaceControl, mParent == null ? null : mParent.getSurfaceControl());if (mLastRelativeToLayer != null) {t.setRelativeLayer(mSurfaceControl, mLastRelativeToLayer, mLastLayer);} else {t.setLayer(mSurfaceControl, mLastLayer);}for (int i = 0; i < mChildren.size(); i++)  {SurfaceControl sc = mChildren.get(i).getSurfaceControl();if (sc != null) {t.reparent(sc, mSurfaceControl);}}if (mOverlayHost != null) {mOverlayHost.setParent(t, mSurfaceControl);}scheduleAnimation();}

代码解析

  1. 首先会通过t.remove(mSurfaceControl);移除当前Task的mSurfaceControl
  2. 在重新mWmService.makeSurfaceBuilder一个新的Builder b,设置他的层级和名字
  3. setInitialSurfaceControlProperties(b);重新创建一个新的SurfaceControl
  4. 创建完成后在把当前的Task重新挂载

看着也没有什么问题,我们在看看这个Builder b的Builder是什么

他是SurfaceControl中的一个内部类,而且他的mFlags = HIDDEN的状态默认就是隐藏

我们接着看setInitialSurfaceControlProperties(b);这个SurfaceControl是怎么创建的

    void setInitialSurfaceControlProperties(Builder b) {setSurfaceControl(b.setCallsite("WindowContainer.setInitialSurfaceControlProperties").build());if (showSurfaceOnCreation()) {Slog.d(TAG,"setInitialSurfaceControlProperties "+mSurfaceControl);getSyncTransaction().show(mSurfaceControl);}updateSurfacePositionNonOrganized();if (mLastMagnificationSpec != null) {applyMagnificationSpec(getSyncTransaction(), mLastMagnificationSpec);}}

是通过Builder b,直接Build()一个SurfaceControl一个出来

if (showSurfaceOnCreation()) {Slog.d(TAG,"setInitialSurfaceControlProperties "+mSurfaceControl);getSyncTransaction().show(mSurfaceControl);}

通过showSurfaceOnCreation()来判断当前的mSurfaceControl是否因该显示,这个showSurfaceOnCreation是

他是WMS中容器的基类中的一个基本方法,默认是true,默认是需要显示的,Task是他的子类是可以复写的

Task返回的就是fals,表示不需要显示,就不会执getSyncTransaction().show(mSurfaceControl);来显示这个Task,然后前面创建的Builder的时候默认也是mFlags = HIDDEN 隐藏,导致Task挂载在了一个是隐藏的mSurfaceControl的上了导致的下面的子窗口黑屏了

怎么解决呢?

我的解决方案是在Task中新增判断当前返回的showSurfaceOnCreation()的状态 亲测可行

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com