关闭

Android源码剖析之Framwork层消息传递(Wms到View)

1352人阅读 评论(0) 收藏 举报
分类:



 本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处!


前面讲过Wms、Ams与Activity的一系列交互,包括创建过程、消息传递、窗口展示等,紧接上篇介绍最终的实现者-窗口和View,上篇对窗口已经有了比较多的介绍,本篇我们再对View再更深一步的了解。

首先明确下View的功能,主要用来展示画布即交互的图片背景等,而且承接各种手势动作消息,以及这两者之间的一系列内容;其他的属于窗口的概念;也可以说内容展示除了窗口就是View。

消息分发指:1、将触摸、键盘输入等消息转化成操作系统可识别的信号2、判断按键消息直接发给当前窗口进入View,触摸消息根据坐标匹配窗口3、最终处理消息。

界面绘制指:1、计算视图大小执行measure方法2、为视图分配位置执行layout方法3、将视图绘入窗口即draw方法。而View所有的功能将围绕这两点展开。

就第一点先说说,用户消息类型指Wms将硬件物理消息转化成统一格式消息,分为三类:按键消息、触摸消息和轨迹球消息(此消息API的Demo中可见,游戏中比较常见)。而消息的组成由以下三项:Action(上和下)、KeyCode(键代码0-9a-z)、Repeat(重复次数)。PS:由于安卓系统没有苹果系统全面,按键消息不断发出,安卓需要自己定义滑动速度和动作逻辑如消息延迟动作+延迟时间(500ms),因此安卓开发者也可以对此进行拓展。按键消息只有上和下,而触摸消息比较多样化,下面就拿它作为例子讲一讲:

Action:屏幕一般支持多点触控,比按键多出POINTER_DOWN2、POINTER_UP2等

EventTime和DownTime:消息发生时间和按下时间,用以区别按键和滑动事件

Pressure:力度大小,可大于1

Size:电容触摸的面积大小,0-1之间

getX(size)和getY(size):触摸点的x和y坐标

按键消息派发过程:比较简单,不再用图形展示,直接写步骤;先说长按事件

1、生理长按(native C++中定义,区别于长按延迟500ms)时间,首次按下不松手,会启动二次长按

2、按下后,如View类无处理,且来自于DPAD_CENTER,则View启动异步消息加调onLongClick事件

再说点击事件

1、底层得到按键消息后,回调ViewRoot的InputHandler中的handleKey函数,再调用dipatchKey函数,发送DISPATCH_KEY消息,让deliverKeyEvent方法处理:

一、执行mView.dispatchKeyEventPreIme():在输入法之前处理,这样重写此方法返回true,可以拦截Ime

二、派发消息到输入法中

三、执行deliverKeyEventToViewHierarchy,传递给真正要处理的视图;此时还要做几件事:判断消息是否导致离开触摸模式、将消息给到根View如应用窗口即PhoneWindow的DecorView,依次处理音量键、系统快捷键、菜单键、Activity到ViewGroup或非应用窗口直接到ViewGroup(如状态栏),未处理消息最后回传到PhoneWindow的onKeyEvent(Up或Down)方法或ViewGroup的onTouchEvent。


PS:上面讲到派发事件到根视图,其中有项是到Activity,先执行dispatchKeyEvent回调onUserInteraction、Window对象的superDispatchKey、KeyEvent.diapatch如无调用否则停止-调用state.startTracking对消息跟踪和回调receiver.onKeyLongPress完成长按处理代码,继承后不执行下步,再执行onKeyDownView中-按键消息是DPAD_CENTER或KEYCODE_CENTER代表确定,判断是否可按,是否可长按,longClick和showContextMenu发生在这里;Activity中-处理Back键,判断mDefaultKeyMode如DEFAULT_KEYS_DISABLE什么也不干、DIALER拨号程序、SHORTCUT快捷键、SEARCH_LOCAL/GLOBAL本地或全局搜索处理相关逻辑,键转字符keyMode,启动相关Activity;PhoneWindow-记得前面讲过,再讲一遍,依次判断执行音量键、播放器键(一般没有)、相机键、菜单键、拨号键、搜索键和onKeyUp(同前者)


按键与触摸最大区别在于:

前者需要先经过Wms(如上面括号里执行的),后者直接进入View;

其次前者是父视图(super.dispatchKeyEvent)先处理消息,然后才是子视图,后者恰恰相反;

前者有系统键,后者要确实处理View,而查收的方法。

触摸消息发生时,区分应用窗口和非应用窗口,

前者对应PhoneWindow的DecorView类型,如果存在Callback对象,调用dispathTouchEvent,则执行Activity的,然后再执行Window的,最后调用mDecorView.onTouchEvent(当然之前要计算是否拦截),不存在则直接调用ViewGroup的

后者对应ViewGroup类型,如果onInterceptTouchEvent未拦截(默认不拦截),则直接分发给子View。

PS:如利用onTouchEvent却没有调用父类此方法,则触摸、点击和长按事件均不会触发,过程tap->press->longpress。


View的绘制上面已讲,那么诱因是什么?1、内部状态发生变化调用rqeustFocus   2、添加或删除子View调用requestLayout   3、大小发生变化调用invalidate,后两者可见性发生改变时也会涉及到。


列举几个比较常见的方法作为结束:

refreshDrawableList:为视图赋予不同的Drawable对象

onFocuseChanged:处理焦点变化的逻辑,输入法与View间通过window来交互

setVisibility:设置可见性,可见到不可见不会调用requestLayout,而到GONE则需要调用

invalidate:对View树重绘,一般requestLayout之后均会调用,顺序先根后子

requestFocus:使某视图获得焦点,直接调用或方向键移动

measure:measuredHeight=bottom-top measuredWidth=right-left EXACTLY=MATCH-PARENT,不可重载 AT_MOST=WARP_CONTENT,UNSPECIFIED不确定;慎用weight(重写指子类功能变异,重载指子类功能变多)

generateDefaultLayoutParams:如ViewGroup无重载,则设置margin无效;生成默认LayoutParmas

layout:布局控件,获得子View宽度、根据gravity决定位置、为子View分配位置

draw:绘制界面;dispatchDraw绘制子视图;需要Surface配合,分两种,一种是显卡一种是CPU模拟的,从中获得Canvas对象;onDrawScrollBar绘制滚动条;设置scale和matrix,以及translatet和rotate


View的功能和特色就如上所述,至于发挥的空间,则在各大App均有表现,需要自己慧眼识珠了。

最后给出屏幕绘图的过程


有关消息在硬件层的分发到此为止,View内分发的分析,请看下面

实例分析:Android中级第十一讲之MotionEvent的分发、拦截机制分析

有的同学嫌本篇介绍的太少,那再就拿一张图来讲讲消息分发机制



注:此View写在xml中,未写布局包含,是一个LinearLayout。

大家可以看到当View执行dispatchTouchEvent后,一般未处理会传给基类处理(默认是framelayout,而mainView还有linearlayout父类),然后传给Activity,最后传给phoneWindow的DecorView处理;最下面绿色圈住的,指下一节使用MessageQueue来处理用户消息,


然后执行ActivityThread和ZygoteInit的main方法

而执行这一事件分发,需要MainThread、两个Binder和一个RenderThread,RenderThread负责分发硬件消息,由一个Binder发出,通过IPC机制传递给窗体层的Binder,窗体层Binder再调用MainThread执行上面一系列流程,实际上也就清楚了底层消息如何从硬件层到窗体层的。


剩下一个问题,空Activity的convertView到底有几个层级?


默认的Activity的convertView有三个层次,其实最低层次id为content,跟tableActivity类似。

消息先由DecorView处理,如果不处理,则分发到下面的ViewGroup和View;如果还没处理则上传给PhoneWindow,最后给Activity.

另外关于消息传递,通过InputDispatcherThread来执行,由InputReader读取,通过InputChannel,由InputDispatcher来传递,

最后调用ViewRoot的dispatchMotion和dispatchKey来传递给页面。


如何自定义各种形状的View,定义多种形状如Rect、Triangle在onDraw方法画入即可。


Binder传输性能高、安全性高、CS架构,通信由Client、ServiceManger、Binder驱动和Server组成,只有驱动在内核空间,其他

均在用户空间。

通信机制:Service向ServiceManager注册,得到虚拟的Uid和Pid,使用Binder通信;Client向ServiceManager请求,得到虚拟的Uid和Pid,以及目标对象的Proxy,底层通过硬件协议传输,使用Binder通讯。

通信时Client手持Proxy,ServiceManger进行转换,调用到Service。三者运行在三个独立进程中。Client/Sever全双工,互为Sever/Client



1
1
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

Android Touch事件传递机制全面解析(从WMS到View树)

转眼间近一年没更新博客了,工作一忙起来,很难有时间来写博客了,由于现在也在从事Android开发相关的工作,因此以后的博文也会更多地专注于这一块。 这篇文章准备从源码层面为大家带来Touch事件的传...
  • mmc_maodun
  • mmc_maodun
  • 2015-12-21 07:43
  • 8197

WmS详解(二)之如何理解Window和窗口的关系?基于Android7.0源码

上篇博客(WmS详解(一)之token到底是什么?基于Android7.0源码)中我们简要介绍了token的作用,这里涉及到的概念非常多,其中出现频率最高的要数Window和窗口这一对搭档了,那么我们...
  • u012702547
  • u012702547
  • 2016-11-19 22:29
  • 2349

Android源码剖析之Framwork层后记篇(硬件消息传递、apk管理、输入法框架、编译过程)

本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 既然写到后记篇,就代表本系列到此为止,暂时告一段落;其他一些Manager随后有时间再补,就像源码的...
  • liuxian13183
  • liuxian13183
  • 2016-09-01 12:06
  • 1537

Android源码剖析之Framwork层后记篇

有关资源访问: data/app:apk被复制后的目录,系统应用放在system/app目录下 data/dalvik-cache:class.dex的存放目录或odex data/...
  • qq_29493705
  • qq_29493705
  • 2016-09-02 10:48
  • 178

解析 ViewTreeObserver 源码,体会观察者模式、Android消息传递(上)

从 ViewTreeObserver 源码出发,带你剖析 ViewTreeObserver,并间接体会观察者(Observer)模式、Android消息传递机制在其中的使用。
  • My_TrueLove
  • My_TrueLove
  • 2016-08-25 02:14
  • 1525

Android22_Handler消息传递机制——源码赏析

Android的消息处理有四个核心类:Handler、Looper、Message、MessageQueue,都在android.os包中。 一、线程的魔法师 Looper L...
  • u011386687
  • u011386687
  • 2015-04-01 16:40
  • 306

Android 源码解析Handler消息传递机制

Android 源码解析Handler消息传递机制, android中可以使用Handler机制进行跨线程消息传递。本文将站在源码的角度详细分析handler的消息传递机制。
  • Zz110753
  • Zz110753
  • 2017-05-18 22:45
  • 220

从Android源码角度对Handler,MessageQueue,Looper之间消息传递工作原理的理解

先总结一下Handler,MessageQueue,Looper之间消息传递的工作原理和相关异常信息,后面进行源码分析。 1 主线程中创建唯一的一个Looper,在Looper对象中,创建Messag...
  • yalinfendou
  • yalinfendou
  • 2015-03-15 13:10
  • 854

Android消息传递源码理解。Handler,Looper,MessageQueue,Message

Android中消息传递模块差不多看了好几次,虽然每次看的方式都差不多但是还是发觉的到每次看了之后,理解的更清晰一点。 关于这个模块的文章数不胜数,但是最重要的还是自己动手理解一遍更好。 会牵扯到的几...
  • xxm282828
  • xxm282828
  • 2015-04-04 16:20
  • 1260

从源码分析Android中Handler的消息传递机制

从源码分析Android中Handler的消息传递机制
  • wujiangming7
  • wujiangming7
  • 2016-12-06 00:31
  • 141
    个人资料
    • 访问:507567次
    • 积分:7063
    • 等级:
    • 排名:第3766名
    • 原创:162篇
    • 转载:8篇
    • 译文:5篇
    • 评论:205条
    博客专栏
    简介(Introduce)
    本博是个人的行业经验及感悟,为初中高级开发者提供一个进步的平台,欢迎来信咨询!写信>>
    推荐
    独立博客:XingtanXue

    网络编程:服务器编程

    QQ群:102785131

    代码片断:tiicle
    站点统计


    添加流量统计