1、Handler 机制

Android 中主线程也叫 UI 线程,那么从名字上我们也知道主线程主要是用来创建、更新 UI 的,而其他耗时操作,比如网络访问,或者文件处理,多媒体处理等都需要在子线程中操作,之所以在子线程中操作是为了保证 UI 的流畅程度,手机显示的刷新频率是 60Hz,也就是一秒钟刷新 60 次,每16.67 毫秒刷新一次,为了不丢帧,那么主线程处理代码最好不要超过 16 毫秒。当子线程处理完数据后,为了防止 UI 处理逻辑的混乱,Android 只允许主线程修改 UI,那么这时候就需要 Handler来充当子线程和主线程之间的桥梁了。
我们通常将 Handler 声明在 Activity 中,然后覆写 Handler 中的 handleMessage 方法,当子线程调用 handler.sendMessage()方法后 handleMessage 方法就会在主线程中执行。这里面除了 Handler、Message 外还有隐藏的 Looper 和 MessageQueue 对象。在主线程中 Android 默认已经调用了 Looper.preper()方法,调用该方法的目的是在 Looper 中创 建 MessageQueue 成 员 变 量 并 把 Looper对象绑定到当前线程中。 当调用 Handler 的sendMessage(对象)方法的时候就将 Message 对象添加到了 Looper 创建的 MessageQueue队列中,同时给 Message 指定了 target 对象,其实这个 target 对象就是 Handler 对象。主线程默
认执行了 Looper.looper () 方法, 该方法从 Looper 的成员变量 MessageQueue 中取出 Message,然后调用 Message 的 target 对象的 handleMessage()方法。这样就完成了整个消息机制。

2、事件分发机制

2.1 事件分发中的 onTouch 和 onTouchEvent 有什么区别,又该如何使用?
这两个方法都是在 View 的 dispatchTouchEvent 中调用的,onTouch 优先于 onTouchEvent执行。如果在 onTouch 方法中通过返回 true 将事件消费掉,onTouchEvent 将不会再执行。另外需要注意的是,onTouch 能够得到执行需要两个前提条件,第一 mOnTouchListener 的值不能为空,第二当前点击的控件必须是 enable 的。因此如果你有一个控件是非 enable 的,那么给它注册 onTouch 事件将永远得不到执行。对于这一类控件,如果我们想要监听它的 touch 事件,就必须通过在该控件中重写 onTouchEvent 方法来实现。

2.2 请描述一下 Android 的事件分发机制

Android 的事件分发机制主要是 Touch 事件分发,有两个主角:ViewGroup 和 View。Activity的 Touch 事件事实上是调用它内部的 ViewGroup 的 Touch 事件,可以直接当成 ViewGroup 处理。View 在 ViewGroup 内, ViewGroup 也可以在其他 ViewGroup 内, 这时候把内部的 ViewGroup当成 View 来分析。
先分析 ViewGroup 的处理流程:首先得有个结构模型概念:ViewGroup 和 View 组成了一棵树形结构,最顶层为 Activity 的 ViewGroup,下面有若干的 ViewGroup 节点,每个节点之下又有若干的 ViewGroup 节点或者 View 节点,依次类推。如图:

当一个 Touch 事件(触摸事件为例)到达根节点,即 Acitivty 的 ViewGroup 时,它会依次下发,下发的过程是调用子 View(ViewGroup)的 dispatchTouchEvent 方法实现的。简单来说,就是ViewGroup 遍历它包含着的子 View,调用每个 View 的 dispatchTouchEvent 方法,而当子 View为 ViewGroup 时,又会通过调用 ViwGroup 的 dispatchTouchEvent 方法继续调用其内部的 View的 dispatchTouchEvent 方法。上述例子中的消息下发顺序是这样的:①-②-⑤-⑥-⑦-③-④。
dispatchTouchEvent 方法只负责事件的分发,它拥有 boolean 类型的返回值,当返回为 true 时,顺序下发会中断。在上述例子中如果⑤的dispatchTouchEvent 返回结果为 true,那么⑥-⑦-③-④将都接收不到本次 Touch 事件。

1.Touch 事 件 分 发 中 只 有 两 个 主 角 :ViewGroup 和 View。ViewGroup 包 含onInterceptTouchEvent 、 dispatchTouchEvent、onTouchEvent 三个相关事件。 View包含dispatchTouchEvent、onTouchEvent 两个相关事件。其中 ViewGroup 又继承于 View。

2.ViewGroup 和 View 组成了一个树状结构,根节点为 Activity 内部包含的一个 ViwGroup。

3.触摸事件由 Action_Down、Action_Move、Aciton_UP 组成,其中一次完整的触摸事件中,Down 和 Up 都只有一个,Move 有若干个,可以为 0 个。

4.当 Acitivty 接收到 Touch 事件时,将遍历子 View 进行 Down 事件的分发。ViewGroup 的遍历可以看成是递归的。分发的目的是为了找到真正要处理本次完整触摸事件的 View,这个 View 会在 onTouchuEvent 结果返回 true。

5.当某个子 View 返回 true 时, 会中止 Down 事件的分发, 同时在 ViewGroup 中记录该子 View。接下去的 Move 和 Up 事件将由该子 View 直接进行处理。 由于子 View 是保存在 ViewGroup 中的,多层 ViewGroup 的节点结构时,上级 ViewGroup 保存的会是真实处理事件的 View 所在的ViewGroup 对象:如 ViewGroup0-ViewGroup1-TextView 的结构中,TextView 返回了 true,它将被保存在 ViewGroup1 中,而 ViewGroup1 也会返回 true,被保存在ViewGroup0 中。当 Move和 UP 事件来时,会先从 ViewGroup0 传递至 ViewGroup1,再由 ViewGroup1 传递至 TextView。

6.当 ViewGroup 中所有子 View 都不捕获 Down 事件时,将触发 ViewGroup 自身的 onTouch事件。触发的方式是调用 super.dispatchTouchEvent 函数,即父类 View 的 dispatchTouchEvent方法。在所有子 View 都不处理的情况下,触发 Acitivity 的 onTouchEvent 方法。
7.onInterceptTouchEvent 有两个作用:1.拦截 Down 事件的分发。2.中止 Up 和 Move 事件向目标 View 传递,使得目标 View 所在的 ViewGroup 捕获 Up 和 Move 事件。

3、子线程发消息到主线程进行更新 UI,除了 handler 和 AsyncTask,还有什么?

(1)用 Activity 对象的 runOnUiThread 方法更新在子线程中通过 runOnUiThread()方法更新 UI:

(2)用 View.post(Runnable r)方法更新 UI

4、子线程中能不能 new handler?为什么?

不能,如果在子线程中直接 new Handler()会抛出异常 java.lang.RuntimeException: Can't create handler inside thread that has not called

Android面试题--事件处理的更多相关文章

  1. Android面试题收集(有具体答案)

    Android面试题目及其答案 1.Android dvm的进程和Linux的进程, 应用程序的进程是否为同一个概念 DVM指dalivk的虚拟机.每个Android应用程序都在它自己的进程中执行,都 ...

  2. 【Android面试】Android面试题集锦 (陆续更新)(最新2012-6-18) eoe上看到的

    ===============eoeAndroid社区推荐:======================= 1.Android开发新浪面试题[开发者必看哦]下载地址 http://www.eoeand ...

  3. Android的Touch事件处理机制

    Android的Touch事件处理机制比较复杂,特别是在考虑了多点触摸以及事件拦截之后. Android的Touch事件处理分3个层面:Activity层,ViewGroup层,View层. 首先说一 ...

  4. 安卓Android面试题大全

    56个问题都是经常用到的,可以深入研究下,也是必须掌握的开发必备知识. 安卓Android面试题汇总 搜集了一些Android面试题目,供将要面试或者正在面试的朋友参考. 1, 谈谈你对Activit ...

  5. Android 面试题总结

    Android 面试题总结(不断更新) 1.INETNT几种有关Activit的启动方式FLAG_ACTIVITY_BROUGHT_TO_FRONT 将ACTIVITY带到最前面FLAG_ACTIVI ...

  6. Android面试题整理【转载】

      面试宝典(5)  http://www.apkbus.com/android-115989-1-1.html 面试的几个回答技巧 http://blog.sina.com.cn/s/blog_ad ...

  7. 19、android面试题整理(自己给自己充充电吧)

    (转载,出处丢失,请原作者原谅,如有意见,私信我我会尽快删除本文) JAVA 1.GC是什么? 为什么要有GC?GC是垃圾收集的意思(Gabage Collection),内存处理是编程人员容易出现问 ...

  8. Android面试题基础(转)

    71道经典Android面试题和答案 1.下列哪些语句关于内存回收的说明是正确的? (b ) A. 程序员必须创建一个线程来释放内存 B.内存回收程序负责释放无用内存 C.内存回收程序允许程序员直接释 ...

  9. Android面试题(文章内容来自他人博客)

    腾讯面试题 1.int a = 1; int result = a+++3<<2; 2.int a = 2; int result = (a++ > 2)?(++a):(a+=3); ...

随机推荐

  1. C#(或者说.NET/Mono)能做的那些事

    不做语言之争,只陈述事实: 1.桌面软件与服务 不仅是在Windows上,有了开源的Mono,在Apple Mac和Linux(如:Ubuntu)上也有C#的施展天地.并且还可以通过mkbundle工 ...

  2. 神通广大的CSS3选择器

    每个前端工程师可能每天都会写一些css,其中选择器是很主要的一部分.但是,大家可能每天写的大多是#id,.class这样的选择器,这并不稀奇,但是如果我们了解并且熟用css3为我们提供的强大并且优雅的 ...

  3. ABP源码分析二十一:Feature

    Feature是什么?Feature就是对function的分类方法,其与function的关系就比如Role和User的关系一样. ABP中Feature具有以下属性: 其中最重要的属性是name, ...

  4. svn diff 详解

    UI版: 如果多人编辑同一段代码,常常容易出现冲突的情况: 如果出现冲突,我们如何解决他呢? 1 可以选择使用自己的文件mime file,也可以使用 他们的文件 their file 2 解决冲突, ...

  5. SVN源代码的版本控制系统使用简介

    SVN是以个开放源代码的版本控制系统,当前最流行的版本控制系统,GIT是近段时间刚兴起的. 下面开始介绍如何安装也配置 1先下载或者从别的地方弄一个安装包(本人是64位的,32位的就用32位的安装包) ...

  6. APP测试点总结(功能,交互,死机崩溃状态分析,容易出错的检查点)

    APP测试点总结(功能,交互,死机崩溃状态分析,容易出错的检查点) 版权声明:本文为博主原创文章,未经博主允许不得转载. 最近涉足APP端测试,常见检查点总结如下:   一.业务方面: 1.  注册( ...

  7. C#设计模式-迭代器模式

    一. 迭代器(Iterator)模式 迭代器是针对集合对象而生的,对于集合对象而言,必然涉及到集合元素的添加删除操作,同时也肯定支持遍历集合元素的操作,我们此时可以把遍历操作也放在集合对象中,但这样的 ...

  8. 【Win 10 应用开发】获取本机的IP地址

    按照老规矩,也是朋友的建议,老周今天在吹牛之前,先讲一个小故事. 有朋友问我,老周,你现在还发短信吗,你每个月用多少电话费?唉,实话说,现在真的发短信不多了,套餐送的130条短信,每月都发不了一条.至 ...

  9. PHP 高级编程(4/5) - SPL异常类之 LogicException 逻辑异常

    SPL 提供了一系列标准异常.日常的使用中我们应该根据需求科学的使用它们,来使我们的程序更加健壮.LogicException 是从 Exception 基类派生的,没有添加任何附加方法.抛出逻辑异常 ...

  10. pixi.js webgl库

    分析pixi源码,刚搭建环境gulp+webpack,目前正在看... https://github.com/JsAaron/webgl-demo