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

局门户网站的建设方案网站维护服务费

局门户网站的建设方案,网站维护服务费,低功耗集成主板做网站,临沂网站制作费用一#xff0c;先思考何时开始绘制 笔者在这里提醒读者#xff0c;Android的View是UI的高级抽象#xff0c;我们平时使用的XML文件也好#xff0c;本质是设计模式中的一种策略模式#xff0c;其View可以理解为一种底层UI显示的Request。各种VIew的排布#xff0c;来自于开…一先思考何时开始绘制 笔者在这里提醒读者Android的View是UI的高级抽象我们平时使用的XML文件也好本质是设计模式中的一种策略模式其View可以理解为一种底层UI显示的Request。各种VIew的排布来自于开发者编写的XML文件或动态增添删除View这一系列的集合即一种策略。而这种策略最终会被Android系统解析为一种Request请求。什么意思呢就是应用进程在此充当绘制的客户端而服务器是谁SurfaceFinger。记住即便屏幕前是我们所描绘的某种策略绘制的UI那也是Surface系统服务器的Response表现。 希望读者能理解这一点。 接下来笔者假设读者已经了解了Activity启动流程并且当前Activity已经进入onCreate生命周期我们就从这里讲起。 相信各位读者一定对Activity#onCreate中调用setContent方法一定熟悉我们直接看下源码。 很简单拿到Window相信读者明白这个Window就是PhoneWindow在此不赘述。不过笔者仍啰嗦一下这里Activity依然将视图委托给Window其Activity-Window-View之间的关系越来越明显了吧。 然后调用PhoneWindow#setContentView传入layoutId我们继续跟进。 这里的mContentParent就是我们setContent传入View的父View在初始化时这里肯定是null因此调用到installDecor方法。这个方法是什么呢简单来讲这里面创建了一个DecorView并且通过我们常用的findVIewById初始化一些View如mContentParent。 我们回到正轨当DecorView已经创建完毕接下来就是使用LayoutInflater去膨胀我们传入的layoutID其parentView参数时mContentParent。关于如何膨胀读者可以自行解读XML解析实现不过其核心是根据XML的一系列层次结构和属性创建多个View并按照层次与属性赋值而已。 然后呢View从何时添加到所谓的WindowManager中呢 此时我们需要快进到ActivityThread#handleResumeActivity方法。 关键核心在下面 由于视图可见DecorView添加至WindowManager中。在此之前有必要解释下ViewRootImpl是啥。先看下ViewRootImpl的构造方法如下。 核心注意IWIndowSession这是什么呢可以理解为应用进程持有的Window#Takon是Binder接口窗口唯一主要负责与WMS通信。笔者在这里通俗理解为View的抽象顶层它既负责管理底层View事件分发、View绘制等又负责与系统交互是应用层View的顶层通信抽象。 明白了这点我们回到正轨继续分析。 wm.addView将DecorView添加到wm中wm是WindowManagerImpl我们跟进。 委托给mBlobal这是进程唯一的WindowManagerGlobal我们跟进。 上述部分是参数的一系列检查我们继续跟进逻辑 在这里ViewRootImpl这种抽象会发现是在每次添加WindowManagerGlobal时创建。我们继续跟进核心逻辑是root.setView。由于VIewRootImpl#setView太长就不在此截图不过核心逻辑如下 requestLayout我们继续跟进 这里可以理解为View视图逻辑Request创建的起点。检查线程、scheduleTraversals里面便涉及三大流程。那么我们得到第一个答案View从什么时候开始绘制的呢是ActivityThread#handleResumeActivity时通过wm.addView(decorViewl)开始进行绘制。但只有这一个起点吗 相信读者知道对指定View调用类似于setVisibile或TextView#setText时也是绘制的起点。但最终会到哪呢话不多说一看了之。 我们跟进TextView#setText 查看核心逻辑checkForRelayout跟进 不管怎样都会调用到requestLayout方法。这是View内置方法并且用final关键字修饰。我们看下该方法定义。 笔者在这里注意到通过设置mPrivateFlags标记此View强制layout重绘然后请求到mParent.requestLayout。mParent正如笔者所述其顶层一定是VIewRootImpl。那么这里我们发现通过更改子View的属性仍通过委托机制到父View此过程中如果需要自己View绘制流程中更改需标记某些Flag。于是乎我们又来到VIewRootImpl#requestLayout。 有兴趣的读者可自行分析setVisiblity方法会发现仍是设置某种flag到自身mFlag类成员上通过向父View委托最终仍触发VIewRootImpl#requestLayout那么笔者就假设VIewRootImpl#requestLayout是一切绘制流程的起点吧。 二真正绘制前过程 checkThread检查是否requestLayout在UI线程这里的UI线程是主线程。读者在这里思考下假设在Activity#onCreate中在子线程设置TextView#setText会抛出异常吗可能不会为什么呢因为只有在onResume时期才会创建VIewRootImpl而TextView通过setText委托了自己的请求向上传但终点mParent是null也就不会抛出此异常了。 我们继续跟进核心逻辑scheduleTraversals方法。 posySyncBarrier是在当前MessageQueue中插入消息屏障。什么是消息屏障呢笔者在此啰嗦一下。消息屏障的本质在是MessageQueue中插入一条特别的Message其target字段为null代表没有处理者。这个时候所有在消息屏障后面的同步消息都被阻塞只有异步消息能通过屏障执行。如下 那什么是异步呢可以理解为高优先级Message可以插队。我们跟进到Choregrapher看看 通过Message#setAsynchronous为true指定MSG_DO_SCHEDULE_CALLBACK为异步消息action即使上文传入的runnable即VIewRootImpl#TraversalRunnable。我们继续跟进。 笔者在这里不太想暂开讲了上述代码在Choreographer中是与帧同步相关的逻辑感兴趣的读者可自行了解。当满足当前帧条件时执行到Choreographer#doFrame方法。Choreographer#doFrame中会计算下是否有跳帧现象如下 最终执行doCallbacks逻辑 层层递进终于执行VIewRootImpl#TraversalRunnable 在此总结下ViewRootImpl#scheduleTraversals会开启消息屏障这时候在Choreographer中的消息又全部是异步消息那样不管我们的MessageQueue中有多少同步消息也不会延迟帧逻辑就不会造成卡顿。当我们真正执行到scheduleTraversales时就会移除消息屏障调用performTraversals这时候可以说进入了绘制的逻辑。 三所谓的绘制过程 VIewRootImpl#performTraversals该函数在Android中出了名的长笔者在这里挑选核心逻辑解释下。 首先是performMeasuredfs方式去解析每个View的大小这很重要。我们跟进看一下 由于meaure是被final修饰内部会回调onMeasure方法 测量参数widthMeasureSpec和heightMeasureSpec传入。 注意到View的ionMeasure不复杂重点在于VIewGroup提供了measureChildren方法而各个继承ViewGroup的View需在OnMeasure中调用measureChildren才能def测量过程我们跟进 进而继续调用View#measure进而调用setMeasureDimensionRaw随后将测量大小保存到measureHeightmeasureWidth中这样一通操作下来从跟DecorView-每个叶子View其内部大小都被保存接下来我们回到ViewRootImpl#performTraversals中开始performLayout过程此过程众所周知计算出每个View的位置。 跟进到layout 笔者说下核心isLayoutValid返回此次layout是否合理。注意到从子view委托到父view中有设置一些Flag来表示自己需要layout如下 因此只有需要layout的view有此flag就不会全局layout了。 此方法会回调View#Onlayout方法View#Onlayout方法默认无实现 ViewGroup重写此方法标记为abstract意图让ViewGroup的子类必须决定子View的摆放位置 具体的实现感兴趣的读者可以自行阅读比较简单。 那么当ViewTree中所有的view大小和位置都确定后该干什么呢在ViewRootImpl#performTravels中最后调用performDraw方法如下。 注意这很关键。正如笔者前面所说所有的应用层绘制本质是构造一种绘制Request发给服务端SurfaceFinger所以与其说此处是draw不如说是createDrawRequest。不过我们继续看下ViewRootImpl#draw实现。 注意到如下mSurface 这里的mSurface可以理解为DrawRequestClient这个概念在ViewRootImpl中被创建 其lockCavas方法可以同等理解为DrawRequestClient.createRequest即我们向Cavas中添加的各种绘制操作都可以理解为一种请求通过unlockCanvasAndPost本质就是提交请求具体的过程我们稍后再谈。 我们继续跟进逻辑drawSoftware除了每个父View构造自己的请求子View也需要在此添加些什么。 在drawSoftware中 这里的mView是DecorView不再赘述其直接调用View#draw方法默认实现中会绘制前景图、背景图等然后回调众所周知的onDraw方法canvas作为参数传入。 并且调用dispatchDraw方法dfs便利子ViewViewGroup实现了此方法如下 通过drawchild 随后dfs式向下传递canvas对象当收集了此ViewRootImpl的所有绘制请求后。接下来干什么呢笔者猜想该去请求SurfaceFinger真正绘制这些请求了。 四真正的绘制过程 通过三过程ViewRootImpl#draw中最后执行surface.unlockCanvasAndPost方法将绘制请求提交如下 那么笔者对此非常感兴趣因此继续跟踪。 此函数最终调用到nativeUnlockCanvasAndPost方法 我们进入native层看看 在native层先校验surface是否有效如果有效进而调用unlockAndPost方法 由于笔者没有native层的源码阅读起来实在不便。感兴趣的读者可以自行阅读下底层实现吧。不过大意可以说下native层通过与SurfaceFinger进行通信将绘制请求交给SufaceFingerSurfaceFinger会在其后置缓存中绘制内存等到下一给垂直帧信号来到时如果绘制成功则交换前置缓存和后置缓存这样就实现了绘制内容的显示。 另外简单总结下View的绘制流程。 当ActivityResume时或某个View变化时通过委托机制请求到ViewRootImpl方法调用其requestLayout方法这时设置同步屏障。当垂直信号有效移除同步屏障。开始对需要变化的View重新测量、布局最后通过surface拿到canvas将绘制过程添加到canvas中然后与SurfaceFinger通信实现内容的展示。
http://www.w-s-a.com/news/188399/

相关文章:

  • 淮阳城乡建设局网站在线网页翻译软件
  • 什么是电商视觉设计郑州seo服务
  • google网站设计原则青海网站建设与管理
  • 简述网站的创建流程广西网站建设定制
  • 唐河网站制作汉中建设工程招标新闻中心
  • 网站过期就可以抢注PHP框架和wordpress
  • 天津做网站得公司克隆网站到wordpress修改
  • 郫县网站建设网站建设报价单及项目收费明细表
  • 商标做网站logo建网站作业
  • 网站顶部展出的大幅广告中建八局第二建设有限公司
  • 公众微信绑定网站帐号优秀中文网页设计
  • 如何做漫画赚钱的网站企业网站管理系统c
  • 安康公司网站制作搜狗网站
  • 太仓住房与城乡建设局网站注册推广赚钱一个80元
  • wordpress 网站生成app企业网站改版的好处
  • 广州建站服务怎么让客户做网站
  • 南京手机网站设计公司wordpress导航页
  • 娄底市建设网站app网站开发小程序
  • 刷粉网站推广免费网站建设找王科杰信誉
  • 投标建设用地是哪个网站微信小程序多少钱
  • 做玄幻封面素材网站我国数字经济报告
  • 手机网站返回跳转wordpress带颜色的文字
  • 微信群领券网站怎么做创意广告图片
  • 跟我一起做网站嘉兴做网站哪家好
  • 上海知名建站公司山东住房和建设庭网站
  • 深圳市城乡建设部网站首页平台设计方案怎么做
  • 深圳美食教学网站制作wordpress列表图显示标题
  • 怎么做网址导航网站沈阳高端做网站建设
  • 棋牌网站开发需要多少钱整网站代码 带数据 免费 下载
  • 网站建设 sql 模版猎头用什么网站做单