Android源码剖析之Framwork层消息传递(Wms到View)
本文来自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如应用窗口的DecorView或非应用窗口的ViewGroup(依次处理音量键、系统快捷键、Activity、PhoneWindow、最后View)、未处理消息是否会引起焦点切换、找到获得焦点的view
PS:上面讲到派发事件到根视图,其中有项是到Activity,先执行dispatchKeyEvent(回调onUserInteraction、Window对象的superDispatchKey、KeyEvent.diapatch如无调用否则停止-调用state.startTracking对消息跟踪和回调receiver.onKeyLongPress完成长按处理代码,继承后不执行下步),再执行onKeyDown(View中-按键消息是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父类),然后传给DecorView的基类处理,最后phoneWindow和Activity;最下面绿色圈住的,指下一节使用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来传递给页面。
Android源码剖析之Framwork层消息传递(Wms到View)的更多相关文章
- Android源码剖析之Framwork层后记篇(硬件消息传递、apk管理、输入法框架、编译过程)
本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 既然写到后记篇,就代表本系列到此为止,暂时告一段落:其他一些Manager随后有时间再补,就像源码的 ...
- Android源码剖析之Framework层升级版(窗口、系统启动)
本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 看本篇文章之前,建议先查看: Android源码剖析之Framework层基础版 前面讲了frame ...
- Android源码剖析之Framework层进阶版(Wms窗口管理)
本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 上一篇我们主要讲了Ams,篇幅有限,本篇再讲讲Wms,即WindowManagerService,管 ...
- Android源码剖析之Framework层基础版(窗口、linux、token、Binder)
本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 关于Framework,就是应用层底下的控制层,离应用层最近,总想找个机会,写写WindowMang ...
- Android源码剖析之Framework层实战版(Ams管理Activity启动)
本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 讲到实战,就不得不拿两个例子来说明,本篇想拿的是应用最广泛的两个:Ams和Wms,一个管理activ ...
- 玩转Android之Picasso使用详详详详详详解,从入门到源码剖析!!!!
Picasso是Squareup公司出的一款图片加载框架,能够解决我们在Android开发中加载图片时遇到的诸多问题,比如OOM,图片错位等,问题主要集中在加载图片列表时,因为单张图片加载谁都会写.如 ...
- (转)Android学习进阶路线导航线路(Android源码分享)
转载请注明出处:http://blog.csdn.net/qinjuning 前言:公司最近来了很多应届实习生,看着他们充满信心但略带稚气的脸庞上,想到了去年的自己,那是的我是不是也和 现在的他们一 ...
- 访何红辉:谈谈Android源码中的设计模式
最近Android 6.0版本的源代码开放下载,刚好分析Android源码的技术书籍<Android源码设计模式解析与实战>上市,我们邀请到它的作者何红辉,来谈谈Android源码中的设计 ...
- 老李推荐:第5章5节《MonkeyRunner源码剖析》Monkey原理分析-启动运行: 获取系统服务引用
老李推荐:第5章5节<MonkeyRunner源码剖析>Monkey原理分析-启动运行: 获取系统服务引用 上一节我们描述了monkey的命令处理入口函数run是如何调用optionP ...
随机推荐
- 编译x264 for ios
Tested with: x264-snapshot-20140914-2245 我用的是x264-snapshot-20150813-2245.tar.bz2 Xcode 7 依赖gas-prep ...
- Spring的循环依赖问题
spring容器循环依赖包括构造器循环依赖和setter循环依赖,那Spring容器如何解决循环依赖呢?首先让我们来定义循环引用类: 在Spring中将循环依赖的处理分成了3种情况: 构造器循环依赖 ...
- SU unif2命令学习
- LightOJ1316 A Wedding Party(状压DP)
这题事实上只需要关心15个商店和一个起点一个终点,预处理出这几个点之间的最短距离.Floyd会超时,用Dijkstra即可. 然后就是dp[u][S]表示已经经过商店集合S且当前在第u个商店所花的最少 ...
- 【wikioi】1403 新三国争霸(dp+kruskal)
http://wikioi.com/problem/1403/ 一开始的确感觉和bzoj1003很像,不同的是这里还要求联通,求最小的边. 我们可以想到用最小生成树(为嘛我自己想不到呢..) 我们可以 ...
- WebRTC手记之框架与接口
转载请注明出处:http://www.cnblogs.com/fangkm/p/4370492.html 上一篇文章简单地介绍了下WebRTC的协议流程,这一篇就开始介绍框架与接口. 一提到框架,本能 ...
- SecureCrt脚本(二)二级对象之Dialog
Crt自动化 测试 SecureCrt脚本 JS脚本 1.引言 2.Dialog属性和方法 2.1.属性 2.2.方法 2.2.1.FileOpenDialog 2.2.2.MessageBox ...
- SQL Server 中 with tmp 临时表的用法
SQL Server 中 with tmp 临时表的用法 ----------with临时表用法,有时候采用临时表比采用in的效率更高,避免了全表扫描. 实例中实现了查询普通题.大题.子题目的sql ...
- iOS移动开发周报-第24期
iOS移动开发周报-第24期 [摘要]:本期iOS移动开发周报带来如下内容:苹果更新了iTunes Connect的设计.UIKit Dynamics 教程:抛掷 Views.iOS APP 架构漫谈 ...
- [LintCode] Cosine Similarity 余弦公式
Cosine similarity is a measure of similarity between two vectors of an inner product space that meas ...