Android的两种事件处理机制

摘要:
UI编程通常都会伴随事件处理,Android也不例外,它提供了两种方式的事件处理:基于回调的事件处理和基于监听器的事件处理。对于基于监听器的事件处理而言,主要就是为Android界面组件绑定特定的事件监听器;对于基于回调的事件处理而言,主要做法是重写Android组件特定的回调函数,Android大部分界面组件都提供了事件响应的回调函数,我们主要重写它们就行。

UI编程通常都会伴随事件处理,Android也不例外,它提供了两种方式的事件处理:基于回调的事件处理和基于监听器的事件处理。

对于基于监听器的事件处理而言,主要就是为Android界面组件绑定特定的事件监听器;对于基于回调的事件处理而言,主要做法是重写Android组件特定的回调函数,Android大部分界面组件都提供了事件响应的回调函数,我们主要重写它们就行。

一 基于监听器的事件处理

相比于基于回调的事件处理,这是更具“面向对象”性质的事件处理方式。在监听器模型中,主要涉及三类对象:

1)事件源Event Source:产生事件的来源,通常是各种组件,如按钮,窗口等。

2)事件Event:事件封装了界面组件上发生的特定事件的具体信息,如果监听器需要获取界面组件上所发生事件的相关信息,一般通过事件Event对象来传递。

3)事件监听器Event Listener:负责监听事件源发生的事件,并对不同的事件做相应的处理。

基于监听器的事件处理机制是一种委派式Delegation的事件处理方式,事件源将整个事件委托给事件监听器,由监听器对事件进行响应处理。这种处理方式将事件源和事件监听器分离,有利于提供程序的可维护性。

举例:

View类中的OnLongClickListener监听器定义如下:(不需要传递事件)

public interface OnLongClickListener {

boolean onLongClick(View v);

}

View类中的OnLongClickListener监听器定义如下:(需要传递事件MotionEvent)

public interface OnTouchListener {

boolean onTouch(View v, MotionEvent event);

}

二 基于回调的事件处理

相比基于监听器的事件处理模型,基于回调的事件处理模型要简单些,该模型中,事件源和事件监听器是合一的,也就是说没有独立的事件监听器存在。当用户在GUI组件上触发某事件时,由该组件自身特定的函数负责处理该事件。通常通过重写Override组件类的事件处理函数实现事件的处理

举例:

View类实现了KeyEvent.Callback接口中的一系列回调函数,因此,基于回调的事件处理机制通过自定义View来实现,自定义View时重写这些事件处理方法即可。

public interface Callback {

// 几乎所有基于回调的事件处理函数都会返回一个boolean类型值,该返回值用于

// 标识该处理函数是否能完全处理该事件

// 返回true,表明该函数已完全处理该事件,该事件不会传播出去

// 返回false,表明该函数未完全处理该事件,该事件会传播出去

boolean onKeyDown(int keyCode, KeyEvent event);

boolean onKeyLongPress(int keyCode, KeyEvent event);

boolean onKeyUp(int keyCode, KeyEvent event);

boolean onKeyMultiple(int keyCode, int count, KeyEvent event);

}

三、比对

基于监听器的事件模型符合单一职责原则,事件源和事件监听器分开实现;

Android的事件处理机制保证基于监听器的事件处理会优先于基于回调的事件处理被触发;

某些特定情况下,基于回调的事件处理机制会更好的提高程序的内聚性。

四、基于自定义监听器的事件处理流程

在实际项目开发中,我们经常需要自定义监听器来实现自定义业务流程的处理,而且一般都不是基于GUI界面作为事件源的。这里以常见的app自动更新为例进行说明,在自动更新过程中,会存在两个状态:下载中和下载完成,而我们的程序需要在这两个状态做不同的事情,“下载中”需要在UI界面上实时显示软件包下载的进度,“下载完成”后,取消进度条的显示。这里进行一个模拟,重点在说明自定义监听器的事件处理流程。

//1.定义事件监听器如下:
public interfaceDownloadListener {
    public void onDownloading(int progress); //下载过程中的处理函数
    public void onDownloaded(); //下载完成的处理函数
}
//2.实现下载操作的工具类:
public classDownloadUtils {
    private static DownloadUtils instance = null;
    privateDownloadUtils() {
    }
    public static synchronizedDownloadUtils instance() {
        if (instance == null) {
            instance = newDownloadUtils();
        }
        returninstance;
    }
    private boolean isDownloading = true;
    private int progress = 0;
    //实际开发中这个函数需要传入URL作为参数,以获取服务器端的安装包位置
    public void download(DownloadListener listener) throwsInterruptedException {
        while(isDownloading) {
            listener.onDownloading(progress);
            //下载过程的简单模拟
            Thread.sleep(1000);
            progress = 0;
            if (progress >= 100) {
                isDownloading = false;
            }
        }
        //下载完成 
listener.onDownloaded();
    }
}
//3.最后在main函数中模拟事件源:
public classDownloadUI {
    public static voidmain(String[] args) {
        try{
            DownloadUtils.instance().download(newMyDownloadListener());
        } catch(InterruptedException e) {
            e.printStackTrace();
        }
    }
    private static class MyDownloadListener implementsDownloadListener {
        @Override
        public void onDownloading(intprogress) {
            System.out.println("下载进度是: " +progress);
        }
        @Override
        public void onDownloaded(intprogress) {
            System.out.println("下载完成);
}         
    }
}

执行结果如下:
Android的两种事件处理机制第1张

Android 编程下 Touch 事件的分发和消费机制 - sunzn - 博客园
http://www.cnblogs.com/sunzn/archive/2013/05/10/3064129.html

免责声明:文章转载自《Android的两种事件处理机制》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇mac 驱动小程序遇到回车符,换行下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

《ArcGIS Runtime SDK for Android开发笔记》

开发笔记之基础教程 ArcGIS Runtime SDK for Android 各版本下载地址 《ArcGIS Runtime SDK for Android开发笔记》——(1)、Android Studio下载与安装 《ArcGIS Runtime SDK for Android开发笔记》——(2)、Android Studio基本配置与使用 《Arc...

安卓基础(点击事件)

今天学习了安卓开发的点击事件,下面我来叙述一下实现点击时间得基本方法: 第一种:在要被点击得控件中加onclick属性 格式:android:onClick="方法名" 例如andoroid:onClick="oneClick" 接下来在对应这个布局得activity中写一个方法,格式为: public void 方法名(View view ){ 方法得执...

Android开发记录

http://coffeelover.iteye.com/blog/1039470 一、Android模拟器相关 1. Android模拟器安装 Market 模拟器默认没有安装 Market,看到网上有较为复杂的安装方法,也有1个简单的,试了简单的,在 Android2.2 模拟器下试过是OK的,简单的方法如下:1) 下载2个文件:GoogleServ...

Android模拟器使用SD卡

在Android手机上,所有的音乐、视频、图像文件都是存储在SD存储卡上的。但是如果想在Android模拟器上也同样能够存储这些内容,就必须先仿真SD存储卡,并让Android手机能够访问仿真出来的SD存储卡。Android SDK 组件的tools目录里,除了emulator这个运行文件外,另外放置mksdcard这个程序,它可以仿真出所需要的SD存储空...

Android程序开发学习笔记系列——基础篇(附源码)

  随着Android的越炒越热和各种应用的不断推出,自己也比较巧合的在去年12月份宽带续费时给送了个电信的Android系统定制机——算是促使我提前了Android开发的学习计划,并给我提供了一个开发测试的'场地'(手机),也更增强了我学习Android程序开发的兴趣——别的市场前景等先暂且不说,至少我学会了,可以做个程序自己用。闲话少说,Android程...

Android Native C 之 Helloworld的四种编译方式_转载

一.编写helloworld.c Android.mk     [root@fontlose jni]# cat hello.c  [cpp] view plaincopyprint?  #include <stdio.h>   int main()   {       printf("Hello World!\n");       ...