Android的事件处理

3.1 Android提供了两套事件处理机制:基于监听的事件处理、基于回调的事件处理。

3.2 基于监听的事件处理

3.2.1 监听的处理模型  主要涉及三类对象:EventSource、Event、EventListener。

Android的事件处理机制是一种委派式(Delegation)事件处理方式:普通组件将整个事件处理委托给特定的对象(事件监听器),可以把所有可能的事件授权给不同的事件监听器来处理,也可以让一类事件都使用同一个事件监听器来处理。

事件监听类是一个特殊的类,必须实现某Listener接口。

3.2.2 事件和事件监听器  如果事件足够简单、事件里封装的信息有限,那就无需封装事件对象、将事件对象出入事件监听器。但对于键盘事件、触摸屏事件,程序需要获取事件发生的详细信息,Android会把事件信息封装成xxxEvent对象,并传给事件监听器。

(源码\03\3.2\plane) 增加触摸事件:

planeView.setOnTouchListener(new View.OnTouchListener(){

@Override public boolean onTouch (View v, MotionEvent event)

......

说明:planeView所使用的事件监听器类是内部类,使用内部类可以在当前类中复用该监听器类;因为监听器类是外部类的内部类,所以可以自由访问外部类的所有界面组件。这也是内部类的两个优势。

3.2.4 外部类作为事件监听器类  这种形式比较少见,因为不利于提高程序的内聚性,不能自由访问创建GUI界面的类中的组件。但如果某个监听器确实需要被多个GUI界面所共享,而且主要完成某种业务逻辑的实现,则可以考虑用外部类的形式定义事件监听器类。

(源码\03\3.2\SendSms)

3.2.5 Activity本身作为事件监听器, 形式简单,但因为Activity的主要职责应该是完成界面初始化工作,界面类需要实现事件监听处理,比较奇怪,容易引起混乱。

3.2.6 匿名内部类作为事件监听器类, 这种形式是目前使用最广泛的事件监听器形式,因为事件处理器的复用价值不大。

3.2.7 直接绑定到标签,直接在界面布局文件中为指定标签绑定事件处理方法。

3.3 基于回调的事件处理

3.3.1 回调机制 对于这种事件处理模型,事件源和事件监听器是统一的,没有事件监听器了。Android为所有GUI组件都提供了一些事件处理的回调方法。继承GUI组件类,并重写该类的事件处理方法。

3.3.2 基于回调的事件传播 几乎所有基于回调的事件处理方法都有一个Boolean类型的返回值,如果返回true,表明该方法已完全处理该事件,该事件不会传播出去;如果返回false,表明该方法并未完全处理该事件,该事件会传播出去,会触发该组件所在Activity的回调方法。

3.3.3 对比

基于监听的事件处理模型具有的优势:分工明确,事件源、事件监听由两个类分开实现,由更好的可维护性;基于监听的事件监听器会被优先触发。

基于回调的事件处理机制的优势:可以更好地提高程序的内聚性。

3.4 响应系统设置的事件

监听系统设置的更改,对系统设置的更改做出响应。如:判断屏幕方向、系统方向的方向导航设备。

3.4.1 Configuration类 专门用户描述设备上的配置信息,既包括用户特定的配置项,也包括系统的动态设备配置。

3.4.2 重写Activity的onConfigurationChanged方法,响应系统设置更改,这个方法是基于回调的事件处理方法。

3.5 Handler消息传递机制

Android的UI操作不是线程安全的,Android的规则是:只允许主线程(UI线程,第一次启动时创建的) 修改Activity里的UI组件。如果新启动的线程需要动态修改界面组件的属性值,需要借助于Handler的消息传递机制来实现。

3.5.1 Handler类的主要作用:在新启动的线程中发送消息,在主线程中获取、处理消息。主线程只能通过回调的方式来适时处理其它线程发生的消息。(源码\03\3.5\HandlerTest)

2.5.2 Handler、Looper、MessageQueue的工作原理: 一个线程只能有一个Looper对象,Looper负责管理MessageQueue,Looper对象会创建MessageQueue,MessageQueue采用先进先出的方式管理消息;主UI线程中,系统为其初始化了一个Looper对象,因此程序直接创建Handler即可;程序员启动的子线程,必须自己创建一个Looper对象,并调用它的prepare()方法和loop()方法启动它即可。(源码\03\3.5\CalPrime)

尽量避免在UI线程中执行耗时操作,因为这可能导致一个“著名”的 异常:ANR异常,应用无法响应输入事件和Broadcast。Android默认约定当UI线程阻塞超过20秒将会引发ANR异常。

3.6 异步任务 AsyncTask

AsyncTask 适用于简单的异步处理,是轻量级的,不需要借助线程和Handler即可实现。

AsyncTask<Params, Progress, Result> 是抽象类,它定义了如下三种泛型类型:Params是启动任务执行的输入参数,Progress是后台任务完成的进度值,Result是后台任务完成后的返回结果。

使用AsyncTask需要创建它的子类,并根据需要实现相关方法。

(源码\03\3.6\AsyncTaskTest)

使用AsyncTask时必须遵守的规则:必须在UI线程中创建它的实例;必须在UI线程中调用它的execute()方法;AsyncTask的onPreExecute()、onPostExecute()等方法只能由Android系统负责调用;每个AsyncTask只能被执行一次。

疯狂Android讲义 - 学习笔记(三)的更多相关文章

  1. 疯狂Android讲义 - 学习笔记(二)

    Android应用的用户界面编程 2.1 界面编程与视图(View)组件 Android应用的绝大部分UI组件放在android.widget.android.view包及其子包中,所有UI组件都继承 ...

  2. 疯狂Android讲义 - 学习笔记(一)

    常用开发工具的用法 android : 启动Android SDK管理器 android --help  查看具体用法 android create avd -n t10 -t 10 -b armea ...

  3. 疯狂Android讲义 - 学习笔记(八)

    第10章 Service与BroadcastReceiver 10.1 Service简介 Service组件也是可执行的程序,有自己的生命周期,创建.配置Service与创建.配置Activity的 ...

  4. 疯狂Android讲义 - 学习笔记(七)

    第8章 Android数据存储与IO  Java IO的数据存储可以移植到Android应用开发上来,Android系统还提供了一些专门的IO API. Android系统内置了SQLite数据库,S ...

  5. 疯狂Android讲义 - 学习笔记(六)

    第7章 7.1 使用简单图片 7.1.1 使用Drawable对象 7.1.2 Bitmap和BitmapFactory 7.2 绘图 7.2.1 Android绘图基础:Canvas.Paint等 ...

  6. 疯狂Android讲义 - 学习笔记(五)

    第五章 Android使用统一的Intent对象来封装“启动意图”,不管是启动Activity.Service组件.或者BroadcastReceiver等,提供了一致的编程模型.Intent设计有点 ...

  7. 疯狂Android讲义 - 学习笔记(四)

    Android应用通常有多个Activity,多个Activity组成Activity栈,当前活动的Activity位于栈顶.Activity相当于Java Web开发的Servlet.当Activi ...

  8. 【疯狂Java讲义学习笔记】【流程控制与数组】

    [学习笔记]1.switch语句后的expression表达式的数据类型只能是byte.short.char.int四个整数类型.String(Java 7后才支持)和枚举类型. 2.数组的长度不可变 ...

  9. 【疯狂Java讲义学习笔记】【数据类型与运算符】

    [学习笔记]1.8bit = 1byte,4byte = 1word.Java中的整型数据有byte(1字节),short(2字节),int(4字节),long(8字节).Java中的浮点数据有flo ...

随机推荐

  1. Linux的原子操作与同步机制

    Linux的原子操作与同步机制   .进程1执行完“mov eax, [count]”后,寄存器eax内保存了count的值0.此时,进程2被调度执行,抢占了进程1的CPU的控制权.进程2执行“cou ...

  2. imagepool前端图片加载管理器(JavaScript图片连接池)

    前言 imagepool是一款管理图片加载的JS工具,通过imagepool可以控制图片并发加载个数. 对于图片加载,最原始的方式就是直接写个img标签,比如:<img src="图片 ...

  3. Webstorm 10 for mac osx 注册机,序列号,kegen

    小菜最近get到mac体验机会,早就耳闻mac非常适合做开发,于是迫不及待的安装各种开发工具,不知不觉,轮到前端开发神器webstorm了,看了一下官网的价格,心拔凉拔凉的. 果断搜索注册机,搜到的结 ...

  4. Go语言实战 - revel框架教程之MongDB的最佳搭档revmgo

    由于revel框架本身对于model层的编写没有提供任何指导,所以在设计这部分的时候就有些犹豫,反复斟酌到底怎样才算是最佳实践. 我在做山坡网的时候刚开始也纠结了一下,拿不准mongodb的sessi ...

  5. jQuery DateTimePicker 日期和时间插件

    jQuery UI很强大,其中的日期选择插件Datepicker是一个配置灵活的插件,我们可以自定义其展示方式,包括日期格式.语言.限制选择日期范围.添加相关按钮以及其它导航等. 日期选择插件是一个配 ...

  6. Java Math 取整的方式

    1.Math.floor floor,英文原意:地板. Math.floor 函数是求一个浮点数的地板,就是 向下 求一个最接近它的整数,它的值肯定会小于或等于这个浮点数. 2.Math.ceil c ...

  7. Pyhton 利用threading远程下发文件和远程执行linux系统命令

    #!/usr/bin/env python # encoding: utf-8 #__author__ = 'cp' #__date__ = '21/07/16 上午 10:32' import th ...

  8. iOS中多线程知识总结(一)

    这一段开发中一直在处理iOS多线程的问题,但是感觉知识太散了,所以就把iOS中多线程的知识点总结了一下. 1.基本概念 1)什么是进程?进程的特性是什么? 进程是指在系统中正在运行的一个应用程序.   ...

  9. ASP.NET MVC5 网站开发实践(一) - 框架(续) 模型、数据存储、业务逻辑

    上次搭建好了项目框架,但还是觉得不太对劲,后来才想起来没有对开发目标进行定位,这个小demo虽然不用做需求分析,但是要实现什么效果还得明确.后来想了一下就做个最简单的网站,目标定为小公司进行展示用的网 ...

  10. Android 内存管理 &Memory Leak & OOM 分析

    转载博客:http://blog.csdn.net/vshuang/article/details/39647167 1.Android 进程管理&内存 Android主要应用在嵌入式设备当中 ...