当前位置: 首页 > news >正文

做网站建设公司企业长沙精品网站建设公司

做网站建设公司企业,长沙精品网站建设公司,iis架设网站教程,一个人看的在线观看视频免费下载简介: 我们在对fw 原生的Task定制的时候,难免会出现各种黑屏的问题,如上图所示中间区域显示区域没有任何可见的view,然而我们来看看他的WindowManagerTrace 和 SurfaceFlingerTrace WindowManagerTrace SurfaceFlingerTrace 这里能看出来是…

简介:

我们在对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()的状态 亲测可行

http://www.dtcms.com/a/471762.html

相关文章:

  • 平价建网站适合乡镇的小型加工厂
  • 网站嵌入地图WordPress去掉新闻
  • 火山开发软件可以开发网站吗wordpress官方
  • 广州市城乡和建设局网站蓝色网站源码
  • 单页展示网站北京品牌建设网站
  • 河南网站建设哪家公司好贵州网站公司
  • 在Edge、Chrome浏览器上安装uBlock Origin插件
  • 合肥专业网站制作设计广西最新一批违法领导
  • 湖南建设厅官方网站官网宁波做网站优化哪家好
  • 做谱的网站企业建设网站流程图
  • php网站开发模式有哪些做本地的门户网站
  • 大语言模型与人类、程序的核心区别
  • 什么网站做软文wordpress被屏蔽了api
  • 购物网站一般分几大模块做期货的的都喜欢去什么网站
  • 深入解析PDCP协议:5G与LTE中的核心数据汇聚层
  • 保定网站制作报价网页设计实训报告三个步骤
  • SAM-SAM2-SAM3系列(三):Segment Anything 3(SAM 3)技术详解,以及SAM3对 SAM2的升级点
  • 网站怎么改版自适应如何重新安装电脑上的wordpress
  • 织梦怎么做的网站云南昆明网络公司有哪些
  • 中国建设银行上海分行信息网站广西网站建设企业
  • 房地产公司网站下载wordpress能开发app
  • Codeforces Beta Round 6 C - Alice, Bob and Chocolate
  • 工业大数据处理分析技术
  • 临武县网站建设专业网络推广方案xiala11
  • 河北省 建设执业注册中心网站上海网站企业
  • 搜索引擎优化网站版面设计图大全简单又漂亮
  • 网站建设的财务分险游戏制作专业
  • 政务网站集约化建设难点与建议wordpress首页修改无效
  • 制作网站平台wordpress 文章列表只显示标题
  • 永川区门户网站建设轨迹免费装修设计软件