加入收藏 | 设为首页 | 会员中心 | 我要投稿 辽源站长网 (https://www.0437zz.com/)- 云专线、云连接、智能数据、边缘计算、数据安全!
当前位置: 首页 > 站长资讯 > 评论 > 正文

Android 绘制原理浅析「干货」

发布时间:2019-08-05 23:09:52 所属栏目:评论 来源:Newpaper
导读:背景 对于Android开发,在面试的时候,经常会被问到,说一说View的绘制流程?我也经常问面试者,View的绘制流程. 对于3年以上的开发人员来说,就知道onMeasure/onLayout/onDraw基本,知道他们呢是干些什么的,这样就够了吗? 如果你来我们公司,我是你的面试

综上,我们大概知道了三者的关系,

  • Activity包含了一个PhoneWindow,
  • PhoneWindow就是继承于Window
  • Activity通过setContentView将View设置到了PhoneWindow上
  • PhoneWindow里面包含了DecorView,最终布局被添加到Decorview上.

理解ViewRootImpl,WindowManager,WindowManagerService(WMS)之间的关系

看了上述三者的关系后,我们知道布局最终被添加到了DecorView上.那么DecorView是怎么被添加到系统的Framework层.

当Activity准备好后,最终会调用到Activity中的makeVisible,并通过WindowManager添加View,代码如下

  1. //Activity  
  2.  void makeVisible() { 
  3.  if (!mWindowAdded) { 
  4.  ViewManager wm = getWindowManager(); 
  5.  wm.addView(mDecor, getWindow().getAttributes()); 
  6.  mWindowAdded = true; 
  7.  } 
  8.  mDecor.setVisibility(View.VISIBLE); 
  9.  } 

那他们到底是什么关系呢? (下面提到到客户端服务端是Binder通讯中的客户端服务端概念. )

以下内容是重点需要理解的部分

  • ViewRootImpl(客户端):View中持有与WMS链接的mAttachInfo,mAttachInfo持有ViewRootImpl.ViewRootImpl是ViewRoot的的实现,WMS管理窗口时,需要通知客户端进行某种操作,比如事件响应等.ViewRootImpl有个内部类W,W继承IWindow.Stub,实则就是一个Binder,他用于和WMS IPC交互。ViewRootHandler也是其内部类继承Handler,用于与远程IPC回来的数据进行异步调用.
  • WindowManger(客户端):客户端需要创建一个窗口,而具体创建窗口的任务是由WMS完成,WindowManger就像一个部门经理,谁有什么需求就告诉它,它和WMS交互,客户端不能直接和WMS交互.
  • WindowManagerService(WMS)(服务端):负责窗口的创建,显示等.

View的重绘

从上述关系中,ViewRootImpl是用于接收WMS传递来的消息.那么我们来看一下ViewRootImpl里面的几个关于View绘制的代码.

在这里在强调一下,ViewRootImpl 两个重要的内部类

  • W类 继承Binder 用于接收WMS 传递来的消息
  • ViewRootHandler类继承Handler 接收W类的异步消息

下面看一下ViewRootHandler类.(以View的setVisible为例.)

  1. // ViewRootHandler(ViewRootImpl的内部类,用于异步消息处理,和Acitivity的启动很像) 
  2. //第一步 Handler接收W(Binder)传递来的消息 
  3. @Override 
  4. public void handleMessage(Message msg) { 
  5.  switch (msg.what) { 
  6.  case MSG_INVALIDATE: 
  7.  ((View) msg.obj).invalidate(); 
  8.  break; 
  9.  case MSG_INVALIDATE_RECT: 
  10.  final View.AttachInfo.InvalidateInfo info = (View.AttachInfo.InvalidateInfo) msg.obj; 
  11.  info.target.invalidate(info.left, info.top, info.right, info.bottom); 
  12.  info.recycle(); 
  13.  break; 
  14.  case MSG_DISPATCH_APP_VISIBILITY://处理Visible 
  15.  handleAppVisibility(msg.arg1 != 0); 
  16.  break; 
  17.  }  
  18.   
  19. void handleAppVisibility(boolean visible) { 
  20.  if (mAppVisible != visible) { 
  21.  mAppVisible = visible; 
  22.  scheduleTraversals(); 
  23.  if (!mAppVisible) { 
  24.  WindowManagerGlobal.trimForeground(); 
  25.  } 
  26.  } 
  27.   
  28.  void scheduleTraversals() { 
  29.  if (!mTraversalScheduled) { 
  30.  mTraversalScheduled = true; 
  31.  mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier(); 
  32.  //开启下次刷新,就遍历View树 
  33.  mChoreographer.postCallback( 
  34.  Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null); 
  35.  if (!mUnbufferedInputDispatch) { 
  36.  scheduleConsumeBatchedInput(); 
  37.  } 
  38.  notifyRendererOfFramePending(); 
  39.  pokeDrawLockIfNeeded(); 
  40.  } 

(编辑:辽源站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

推荐文章
    热点阅读