`
wolfmaster
  • 浏览: 158704 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

Java事件模型与Android事件模型的比较

阅读更多

比较结果:Android借鉴了Java2中的UI事件处理机制,但是,Android又提供了另一种事件處理器(event handler),而这个方式是否与java1.0事件模型一样呢,有待求证。

 

Java事件模型:

我们把JDK1.0事件处理模型成为Java1.0事件模型,而从jdk1.1后的版本事件处理模型称为Java 2事件处理模型。

 

1.  Java1.0事件模型:

dispatchEvent()-postEvent()-handleEvent()

 

在JDK1.0的版本采用用的事件模型,提供了基本的事件处理功能。这是一种包容模型,所有事件都封装在单一的类Event中,所有事件对象都由单一的方法 handleEvent来处理,这些定义都在Component类中。
为此,只有Component类的子类才能充当事件处理程序,事件处理传递到组件层次结构,如果目标组件不能完全处理事件,事件被传递到目标组件的容器。

 

在Java1.0事件处理模型中事件处理是以如下方法执行的。deliverEvent()用于决定事件的目标,目标是处理事件的组件或容器,此过程开始于GUI层的最外部而向内运作。
当按一个button时,如果检测到是该按钮激发的事件,该按钮会访问它的deliverEvent()方法,这一操作由系统完成。一旦识别目标组件,正确事件类型发往组件的postEvent()方法,该方法依次把事件送到handleEvent()方法并且等待方法的返回值。
"true"表明事件完全处理,"false"将使postEvent()方法联系目标容器,希望完成事件处理。

 

2. Java 2事件处理模型:

 

在Java2处理事件时,没有采用dispatchEvent()-postEvent()-handleEvent()方式,采用了监听器类,每个事件类都有相关联的监听器接口。事件从事件源到监听者的传递是通过对目标监听者对象的Java方法调用进行的。
对每个明确的事件的发生,都相应地定义一个明确的Java方法。这些方法都集中定义在事件监听者(EventListener)接口中,这个接口要继承 java.util.EventListener。 实现了事件监听者接口中一些或全部方法的类就是事件监听者。
伴随着事件的发生,相应的状态通常都封装在事件状态对象中,该对象必须继承自java.util.EventObject。事件状态对象作为单参传递给应响应该事件的监听者方法中。发出某种特定事件的事件源的标识是:遵从规定的设计格式为事件监听者定义注册方法,并接受对指定事件监听者接口实例的引用。

 

3. Java事件和万事一样有其生命周期,会出生也会消亡。下图3.1给出了Java事件生命周期的示意图:


 

事件最初由事件源产生,事件源可以是GUI组件Java Bean或由生成事件能力的对象,在GUI组件情况下,事件源或者是组件的同位体(对于Abstract Window Toolkit[awt]GUI组件来说)或组件本身(对于Swing组件来说)。
事件生成后放在系统事件队列内部。现在事件处于事件分发线程的控制下。事件在队列中等待处理,然后事件从事件队列中选出,送到dispatchEvent()方法,dispatchEvent()方法调用processEvent()方法并将事件的一个引用传递给processEvent()方法。
此刻,系统会查看是否有送出事件的位置,如果没有这种事件类型相应的已经注册的监听器,或者如果没有任何组件受到激活来接收事件类型,事件就被抛弃。当然上图显示的是AWTEvent类的子类的生命周期。 dispatchEvent()方法和processEvent()方法把AWTEvent作为一个参数。但对,javax.swing.event并不是AWTEvent子类,而是从EventObject直接继承过来,生成这些事件的对象也会定义fireEvent()方法,此方法将事件送到包含在对象监听器列表内的那种类型的任何监听器。
3.2 Java事件捕获
从上面的分析我们知道,任何事件产生到dispatchEvent()方法分发方法前,所有的事件都是存放在系统事件的队列中,而且所有的事件都由dispatchEvent()方法来分派。所以只要能重载dispatchEvent()方法就可以获取系统的所有事件,包括用户输入事件。一般来说,系统事件队列的操作对用户来说是可以控制。它在后台自动完成所要完成的事情,使用EventQueue类可以查看甚至操纵系统事件队列。
Java提供了EventQueue类来访问甚至操纵系统事件队列。EventQueue类中封装了对系统事件队列的各种操作,除dispatchEvent()方法外,其中最关键的是提供了push()方法,允许用特定的EventQueue来代替当前的EventQueue。
只要从EventQueue类中派生一个新类,然后通过push()方法用派生类来代替当前的EventQueue类即可。这样,所有的系统事件都会转发到派生EventQueue类。

 

而在实际的开发中,我们并不关心事件的分派方式,也就是说,并不会重载dispatchEvent(),

因为我们的目的并不是取系统的所有事件,而是对感兴趣的事件(例如,按键,鼠标的按下与释放)进行处理,而这些事件不会凭空产生,是由事件源(例如,button,window这些GUI组件产生的)。另一个原因是,java2中已经给我们提供了事件监听这种处理方式,而且是非常安全的,并且也易于开发,

 

4. 如何使用事件处理模型对事件进行处理:

作为一个程序开发者,我们所要做的是创建事件监听器对象并且在被激活事件的组件中进行注册。在java中,每一个组件会产生什么样的事件,已经被定义好了。或者说,对于任何一个事件来说,哪些组件可以产生它,已经是确定的了。

 

(1) 为了创建事件监听器以及在被激活事件的组件中进行注册,需要了解以下四个组件概念。

 

事件类、事件监听器、事件处理器和适配器四个组件。

事件类:见图4.1

事件监听器:是interface, 形中XXListener,而且,在java中,这些interface已经被定义好了。用来被实现,它定义了事件处理器(即事件处理的方法原型,这个方法需要被重新实现)。例如,ActionListener接口,

MouseListener接口

WindowListener接口

KeyListener接口

ItemListener接口

MouseMotionListener接口

FocusListener接口

ComponentListener接口

 

 

适配器:因为对于有的事件监听器来说(例如,MouseListener

),java已经提供了实现它的类,那么我们就可以直接继承这个类,来处理事件。

Java提供了表示不同的事件的类, java.util. EventObject是事件顶层类,其层次结构如下:


 

                         图4.1

 

需要说明的是:

̶               EventObjet类提供了getSource()方法获取产生事件的源对象。

̶               AWTEvent类提供了getID() 方法返回事件本性的标识符。例如,如果鼠标事件发生,能够查出是单击、拖拉、按、还是其他操作。

 

(2)程序开发步骤:

所谓的创建事件监听器对象,就是创建一个类,而这个类必须实现形如XXListener的接口(或者继承”已经实现了XXListener的类”),当然,实现这个接口就意味着重写XXListener的方法。例如,对于ActionListener, 只有一个actionPerformed方法:

 

class B1 implements ActionListener {                         // 实现ActionListener

public void actionPerformed(ActionEvent e) {    //重写actionPerformed      getAppletContext().showStatus("Button 1");

}

在被激活事件的组件中注册事件监听器: 即调用形如addXXListener()的方法,例如:

Button b1 = new Button("Button 1"),b1.addActionListener(new B1()); //注册事件监听器,b1就是被激活事件的组件这样一来,当事件被激活时,处理流程如下(根据图3.1对照来看):由于已经通过addActionListener进行了事件监听器的注册,所以,就会调用到特定的事件处理方法,即actionPerformed()函数。这样,执行的结果就要看actionPerformed是具体做什么工作了。 完整的例子(来源于think in java 13.16.1节): //: Button2New.java// Capturing button pressesimport java.awt.*;import java.awt.event.*; // Must add thisimport java.applet.*; public class Button2New extends Applet {  Button    b1 = new Button("Button 1"),    b2 = new Button("Button 2");  public void init() {    b1.addActionListener(new B1());    b2.addActionListener(new B2());    add(b1);    add(b2);  }  class B1 implements ActionListener {    public void actionPerformed(ActionEvent e) {      getAppletContext().showStatus("Button 1");    }  }  class B2 implements ActionListener {    public void actionPerformed(ActionEvent e) {      getAppletContext().showStatus("Button 2");    }  }}  这是最常用的一种方式:定义一个内部类,来实现ActionListener监听器。而在外部类中,定义一个这样的对象,去注册监听器,通过调用addActionListener方法,需要注意的是,这个内部类对象是作为addActionListener的参数,在本类中,是直接作为匿名对象被创建的。这里,也可以不用匿名对象,而直接new 一个对象,然后,这个对象作为参数传给addActionListener。 考虑:不用匿名对象与用匿名对象的区别? 更多的例子,请参考《think in java 13.16》,推荐编码方法见《think in java 13.16.7推荐编码方法》 Android事件模型(从UI角度来说): 从网上摘抄了一些相关文章(共5篇),从这几篇文章来看,Android事件模型与java2的事件模型处理方式一样,对事件的处理,都是采用事件监听器的方式来实现的。

文章1:

Jollen 的 Android 教學,#15: 什麼是事件監聽器(Event Listener)?

 

學會產生基本的UI後,接著就要學習UI的事件處理(UI Events),才能讓UI與使用者「互動」。

什麼是事件監聽器(Event Listener)

UI的使用者事件處理,即View如何處理使用者的操作,是一個重要的課題。View是重要的類別,它是與使用者互動的前線;在Android框架的設計中,以事件監聽器(event listener)的方式來處理UI的使用者事件。

Android框架提供了非常良好的UI事件處理機制。先前的教學提到,View是繪製UI的類別,每個View物件都可以向Android框架註冊一個事件監聽器。每個事件監聽器都包含一個回呼函數(callback method),

這個回呼函數(callback method)主要的工作就是回應或處理使用者的操作。

Event Listener: 以Click Listener為例

以「使用者觸碰(touch)」的動作來說,當View要處理使用者觸碰的事件時,就要向Android框架註冊View.OnClickListener事件監聽器;當「touch」事件發生時,Android框架便回呼事件監聽器裡的回呼函數。

View.OnClickListener是click listener,故名思意,這是UI的「Click動作監聽器」;當使用者對View進行Click操作時(即觸控畫面上的UI元件),Android 框架便會回呼這個View.OnClickListener的回呼函數。

View.OnClickListerner的回呼函數為OnClick()。

這裡所提到的監聽器泛指event listener,主要用來「監聽」使用者的各種動作。除了View.OnClickListener外,Android框架還有以下的event listener(及其callback method):

·View.OnLongClickListener: onLongClick()

·View.OnFocusChangeListener: onFocusChange()

·View.OnKeyListener: onKey()

·View.OnTouchListener: onTouch()

·View.OnCreateContextMenuListener: onCreateContextMenu()

另外一種處理UI事件的機制為事件處理器(event handler),event handler與event listener是不一樣的二種處理機制。在自訂Android component的教學裡,再介紹這個部份。

文章2:

如果玩过数独游戏,就会知道该游戏有时候非常容易,而有时候简直令人抓狂。因此,当用户选择New Game按钮时,就应该弹出一个对话框,要求用户从3个难度级别中选择一个。在Android中,从事件列表中选择某个事件非常容易实现。首先,需要在res/values/strings.xml文件中再添加几个字符串:


其次,使用数组资源在res/values/arrays.xml文件中创建难度列表:


然后,在Sudoku类中再导入几个包:


最后,在onClick()方法的switch语句中添加处理New Game按钮单击事件的代码:


其中,openNewGameDialog()方法的作用是创建一个处理难度列表的用户界面。

 


 

 

setItems()方法有两个参数:条目列表的资源ID和一个监听器,用户选择某个条目时,该监听器将被调用。

现在,运行该程序并按下New Game,将会出现如图3-12中所示的对话框。


图3-12 选择难度级别对话框

实际上,此时我们并不打算开始一次新游戏。因此,当用户选择某个难度级别时,该程序只是利用Log.d()方法输出一条调试消息。Log.d()方法接收两个参数:一个标记字符串和要输出的一条消息。

文章3:

 

Widget中事件监听器的实现

Widget中事件监听器的实现


widget中是没有click listener的,那么如何实现点击的动作呢?我们可以通过广播的形式来替代click linstener。

我们知道widget其实就是一个BroadcastReceiver,所以在AndroidManifest.xml中,注册一个新的action:
<receiver android:name="XXX">
        <meta-data android:name="android.appwidget.provider"
                                android:resource="@xml/XXX">
        </meta-data>
        <intent-filter>
            <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
            <action android:name="com.android.CLICK"></action>
        </intent-filter>
</receiver>

代码中需要触发点击事件的地方发送一个广播:

  Intent intent = new Intent("com.android.CLICK");
  PendingIntent pi = PendingIntent
                                .getBroadcast(context, 0, intent, 0);
  views.setOnClickPendingIntent(R.id.textview, pi);

在widget的onReceive() 方法中接收这个广播:

  public void onReceive(Context context, Intent intent) {
                super.onReceive(context, intent);
                String action = intent.getAction();
                if (action.equals("com.android.CLICK")) {
                        //TODO  处理点击事件
                }
        }

这样就完成了widget中的一次点击事件
 
 
 TOP
 


文章4:

Reference/android/view/View
From Android中文网
Android中文网(androidcn.net) 版权申明 : creativecommons licenses

Jump to: navigation, search

android.view

公有类

android.view.View

java.lang.Object

android.view.View Drawable.Callback KeyEvent.Callback

视图(View)类代表了一种基本的用户界面组成模块。一个视图占据了屏幕上的一个矩形区域,并响应绘制图形和事件处理。视图类是窗体类(Widget)的基类,而窗体类用来生成可交互的用户图形接口(interactive GUI)。

视图类的使用窗口中所有的视图构成一个树形结构。要想增加视图,既可以用直接添加代码的方法,也可以在一个或者多个XML文件中声明新视图构成的树。在视图类的子类中,有的可以用来控制,有的具有显示文字、图片或者其他内容的功能。

当视图树被创建后,以下这若干种通用操作将可以被使用: 1.设置属性(properties):比如,可以设置TextView类的一个实例的文本内容。不同的子类可以用来设置的属性与方法不同。注意:只有编译时能够检测到的属性才可以在XML布局管理(layout)文件中设置。

2.设置输入焦点(focus):为了响应用户输入,整个框架将处理移动的焦点。如果想把焦点强制指向某一个特定的视图,必须调用requestFocus()方法。

3.设置监听器(listener):在视图中,允许设置监听器来捕获用户感兴趣的某些事件。比如说,在所有的视图中,无论视图是获得焦点还是失去焦点,都可以通过设置监听器来捕获。可以通过调用setOnFocusChangeListener(View.OnFocusChangeListener)来注册一个监听器。在其他视图子类中,提供了一些更加特殊的监听器。比如,一个按键(Button)可以触发按键被按下的事件。

4.设置是否可视(visibility):可以通过调用setVisibility(int)来显示或者隐藏视图。

取自"http://www.androidcn.net/wiki/index.php/Reference/android/view/View"

 

文章5:

监听UI事件通知
Some UI notifications are automatically exposed and called by Android. For instance, Activity exposes overrideable methods onKeyDown and onKeyUp, and Widget exposes onFocusChanged(boolean, int). However, some important callbacks, such as button clicks, are not exposed natively, and must be registered for manually, as shown here.

 

   public class SendResult extends Activity   {   /**    * Initialization of the Screen after it is first created.  Must at least    * call setContentView() to    * describe what is to be displayed in the screen.    */   protected void onCreate(Bundle savedValues)   {       ...       // Listen for button clicks.       Button button = (Button)findViewById(R.id.corky);       button.setOnClickListener(mCorkyListener);   }   // Create an anonymous class to act as a button click listener.   private OnClickListener mCorkyListener = new OnClickListener()   {       public void onClick(View v)       {           // To send a result, simply call setResult() before your           // activity is finished.           setResult(RESULT_OK, "Corky!");           finish();       }   };

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/liranke/archive/2009/10/29/4740844.aspx

转自 http://blog.csdn.net/liranke/archive/2009/10/29/4740844.aspx

分享到:
评论

相关推荐

    android使用jpct加载三维模型

    7. **触摸和手势控制**: Android提供了一系列的触摸事件监听器,如`OnTouchListener`,你可以利用这些接口响应用户的触摸操作,改变相机视角或模型的属性,实现3D交互。 8. **性能优化**: 移动设备的硬件资源有限,...

    Android OpenGL绘制STL 3D模型

    在Android应用中,我们可以使用Java或Kotlin的I/O流来读取STL文件,然后将其内容转换为OpenGL可以理解的数据结构。例如,我们可以创建一个`Triangle`类,存储每个三角形的三个顶点和法线向量。 接下来是关键的渲染...

    常见的java,android面试题整理

    面试中可能会涉及String的创建、连接、比较以及与StringBuilder和StringBuffer的区别。 6. **算法和数据结构**: 面试通常会考察基础的排序算法(如冒泡、选择、插入、快速、归并排序)、查找算法(二分查找、哈希表...

    javacv1.1-android-armARM

    JavaCV提供了与原生库类似的API,简化了跨平台的开发工作。 2. **OpenCV**:OpenCV是一个广泛使用的开源计算机视觉库,包含了各种图像处理和计算机视觉算法。在Android平台上,OpenCV可以用于图像识别、特征检测、...

    java jna 调用pytorch c++模型推理

    Java JNA调用PyTorch C++模型推理是一种在Java应用程序中利用PyTorch的深度学习能力的方法。JNA(Java Native Access)是Java平台上的一个库,它允许Java代码直接调用本机库(如C++编写的库),而无需编写JNI(Java ...

    浅谈android线程模型

    ### 浅谈Android线程模型:深入理解与实践 #### 引言 随着智能手机的普及和技术的不断进步,Google的Android操作系统成为了移动设备领域的重要力量。Android不仅为用户提供了丰富的功能,也为开发者提供了广阔的...

    javacv1.1-android-x86X86

    在JavaCV中,JavaCPP负责将Java与OpenCV、FFmpeg等库的C++接口连接起来,使得Java开发者可以方便地调用底层的高性能计算功能。 3. **FFmpeg**:FFmpeg是一个强大的多媒体框架,它能处理音频、视频编码解码,转换、...

    Java基础+Android面试题

    3. Android事件分发机制:解析了触摸事件在Android系统中的传递流程和处理。 4. AsyncTask详解:提供了在后台线程中执行耗时操作,并与UI线程通信的方法。 5. Android并发集合:ArrayBlockingQueue、...

    基于java的Android MVP模型良好的架构设计代码实现

    本篇将深入探讨如何使用Java在Android平台上实现MVP模型,并通过代码实现来展示其优点。 **MVP模式概述** MVP全称为Model-View-Presenter,是一种设计模式,用于分离应用程序的业务逻辑、用户界面和数据模型。它的...

    发送模型基于安卓点触事件

    在Android系统中,触摸事件是用户与设备交互的主要方式之一,尤其在开发移动应用时,理解和处理触摸事件显得尤为重要。本教程将深入探讨如何在Android环境中实现自定义的触控事件,即“发送模型基于安卓点触事件”。...

    用Java实现一个UDP通信模型

    在Android环境中,`DatagramSocket`的使用与Java标准版基本一致,但需确保在正确的线程(如AsyncTask或子线程)中进行网络操作,以避免ANR(Application Not Responding)错误。同时,Android提供了`...

    基于java的VR全景图+Opengl3D模型展示源码

    Java是一种广泛使用的编程语言,尤其在企业级应用和Android开发中占据主导地位。在这个特定的项目中,我们看到的是Java技术被应用于虚拟现实(VR)领域,结合OpenGL 3D图形库来创建全景图和3D模型的展示。这是一个...

    Android-HanLP是由一系列用于自然语言处理模型与算法组成的Java工具包

    HanLP,作为一款由Java编写的高效自然语言处理工具包,为Android开发者提供了丰富的NLP模型和算法,使其能够在移动设备上轻松实现复杂文本处理任务。 HanLP的主要特点: 1. 功能完善:HanLP涵盖了词性标注、分词、...

    android事件的处理模型和多线程的处理方法

    总之,Android事件处理模型通过Input子系统实现了高效的事件分发,而多线程技术则保证了应用的流畅运行和用户体验。理解和掌握这些机制对于开发高质量的Android应用至关重要。开发者需要根据具体需求选择合适的事件...

    android应用java源码

    1. **Android SDK与Java源码关系**: Android SDK(软件开发工具包)包含了开发者构建Android应用所需的所有工具,其中包括Java库。开发者可以使用Java编程语言,配合Android SDK中的API来编写应用。源码揭示了这些...

    【免费】JavaCV Demo Android

    JavaCV(Java Computer Vision)是Java平台上的计算机视觉库,它为开发者提供了访问多个开源...通过深入研究这个示例代码,开发者可以掌握Android与JavaCV、OpenCV的整合技巧,以及如何实现实时的人脸检测和识别功能。

    Android:复杂数据模型的传递

    在Android中,我们可以通过创建Java或Kotlin类来实现这些模型,定义其属性并提供getter和setter方法。 在处理复杂数据模型时,我们可能会遇到多层嵌套的情况,例如一个模型包含另一个模型的引用,或者一个集合包含...

    JVM内存结构、Java内存模型、Java对象模型1

    Java内存模型(JMM)与JVM内存结构不同,它是针对多线程环境下内存访问的抽象模型。JMM确保在多线程环境下,共享变量的读写操作具有正确的顺序和可见性,通过volatile、synchronized等关键字来实现这一目标。JMM关注...

    Android 人脸识别+人脸匹配(OpenCV+JavaCV)

    此外,使用OpenCV和JavaCV时,需要处理好Android平台特有的问题,比如摄像头的预览回调、异步处理图像、内存管理等。同时,由于Android设备硬件和版本的多样性,人脸识别的性能和效果可能因设备而异,因此优化和测试...

Global site tag (gtag.js) - Google Analytics