问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

请简述什么是android事件处理,并分析两种android事件处理机制的实现过程...

发布网友 发布时间:2022-04-26 18:01

我来回答

3个回答

热心网友 时间:2022-04-22 09:42

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

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


一 基于*的事件处理

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

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

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

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


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

举例:

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


[java] view plaincopyprint?

public interface OnLongClickListener {  

   boolean onLongClick(View v);  

}  

public interface OnLongClickListener {
   boolean onLongClick(View v);
}


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

[java] view plaincopyprint?

public interface OnTouchListener {  

   boolean onTouch(View v, MotionEvent event);  

}  

public interface OnTouchListener {
   boolean onTouch(View v, MotionEvent event);
}

二 基于回调的事件处理

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

举例:

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

[java] view plaincopyprint?

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);  

}  

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界面上实时显示软件包下载的进度,“下载完成”后,取消进度条的显示。这里进行一个模拟,重点在说明自定义*的事件处理流程。

4.1)定义事件*如下:

热心网友 时间:2022-04-22 11:00

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界面上实时显示软件包下载的进度,“下载完成”后,取消进度条的显示。这里进行一个模拟,重点在说明自定义*的事件处理流程。
4.1)定义事件*如下:
public interface DownloadListener {
public void onDownloading(int progress); //下载过程中的处理函数
public void onDownloaded(); //下载完成的处理函数
}
4.2)实现下载操作的工具类代码如下:
public class DownloadUtils {

private static DownloadUtils instance = null;

private DownloadUtils() {
}

public static synchronized DownloadUtils instance() {
if (instance == null) {
instance = new DownloadUtils();
}
return instance;
}

private boolean isDownloading = true;

private int progress = 0;

// 实际开发中这个函数需要传入url作为参数,以获取服务器端的安装包位置
public void download(DownloadListener listener) throws InterruptedException {
while (isDownloading) {
listener.onDownloading(progress);
// 下载过程的简单模拟
Thread.sleep(1000);
progress += 10;
if (progress >= 100) {
isDownloading = false;
}
}
// 下载完成
listener.onDownloaded();
}

}
4.3)最后在main函数中模拟事件源:
public class DownloadUI {

public static void main(String[] args) {
try {
DownloadUtils.instance().download(new MyDownloadListener());
} catch (InterruptedException e) {
e.printStackTrace();
}
}

private static class MyDownloadListener implements DownloadListener {

@Override
public void onDownloading(int progress) {
System.out.println("下载进度是:" + progress);
}

@Override
public void onDownloaded() {
System.out.println("下载完成");
}

}

}

热心网友 时间:2022-04-22 12:35

1.监听事件处理
基于监听的事件处理分工明确,可维护性高,且会优先触发。
内部类形式:Class MyClickListener implements View.OnClickListener{ 实现的方法,即事件处理器}
外部类形式:将事件*类定义成一个外部类:public class SendSmsListener implements OnLongClickListener{容易把业务逻辑和显示逻辑耦合,不利于程序的内聚性:p195}
Activity本身作为事件*:让Activity本身实现*接口,并实现处理方法。做法简洁,Activity本身应该完成界面的初始化工作,同时包含事件处理比较混乱。public
匿名内部类形式:btn.setOnClickListener( new OnClickListener(){ 实现时间的处理方法 });
绑定到标签:在XML未指定标签绑定事件处理方法,android:onClick = "clickHandler",写一个clickHandler(){ 处理 }方法。

2.回调事件处理
监听事件处理是委托式处理,回调事件处理是实现组件自己特定的方法来处理事件,没有监听事件。
public MyButton extends Button{
public boolean onKeyDown(int KeyCode,KeyEvent event){
super.onKeyDown(KeyCode,event);
Log.v("返回值","true不会向外扩散");
return true;
}
}
MyButton重写了父类的onKeyDown()方法,不需要绑定监听,自己会处理相应的事件。
回调方法的返回值为true表示能完全处理,不会传播出去。返回false,表示未完全处理,会传播出去。 如果没有完成处理(false),则由*-->事件回调-->传播到activity,都会出发该方法处理。

3.相应系统设置的事件
Configuration类专门用于描述手机上配置信息,包括用户特定配置和系统动态配置。
Configuration cfg = getResources().getConfiguration();获取了Configuration对象可以使用该对象提供的属性来获取系统配置。

4.Handler消息传递机制
主线程又称为UI线程,在主线程不进行耗时操作,这是需要用到handler。耗时操作会引发ANR异常。
Handler类主要有两个作用:在新启动的线程中发送消息至MessageQueue ;在主线程中获取Looper分给他的消息,处理消息。
Looper :每个线程只能拥有一个looper ,负责管理MessageQueue,不断从消息队列中取出消息,分给对应的Handler处理。
MessageQueue :消息队列,采取先进先出的方式管理message。
HandlerMessage() :Handler接收和处理的消息对象。
在主线程中,系统已经初始化了一个Looper对象,因此程序直接创建Handler并收发消息即可;而自己启动的子线程,必须自己创建一个Looper对象并启动它:Looper.prepare() 创建对象并保证只有一个Looper对象。

Android不允许在子线程中更改UI组件,需要在子线程中更改界面组件必须用handler实现。

5.异步任务

实现异步任务的机制有两种:Handler和AsyncTask。
AsyncTask<Params,Progress,Result>
三种泛型类型分别代表“启动任务执行的输入参数”、“后台任务执行的进度”、“后台计算结果的类型”。在特定场合下,并不是所有类型都被使用,如果没有被使用,可以用java.lang.Void类型代替。

一个异步任务的执行一般包括以下几个步骤:
1.execute(Params... params),执行一个异步任务,需要我们在代码中调用此方法,触发异步任务的执行。
2.onPreExecute(),在execute(Params... params)被调用后立即执行,一般用来在执行后台任务前对UI做一些标记。
3.doInBackground(Params... params),在onPreExecute()完成后立即执行,用于执行较为费时的操作,此方法将接收输入参数和返回计算结果。在执行过程中可以调用publishProgress(Progress... values)来更新进度信息。
4.onProgressUpdate(Progress... values),在调用publishProgress(Progress... values)时,此方法被执行,直接将进度信息更新到UI组件上。
5.onPostExecute(Result result),当后台操作结束时,此方法将会被调用,计算结果将做为参数传递到此方法中,直接将结果显示到UI组件上。

在使用的时候,有几点需要格外注意:
1.异步任务的实例必须在UI线程中创建。
2.execute(Params... params)方法必须在UI线程中调用。
3.不要手动调用onPreExecute(),doInBackground(Params... params),onProgressUpdate(Progress... values),onPostExecute(Result result)这几个方法。
4.不能在doInBackground(Params... params)中更改UI组件的信息。
5.一个任务实例只能执行一次,如果执行第二次将会抛出异常。
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
抖音弹幕怎么关掉?怎么关闭抖音弹幕? 惠普LaserJet P3005D是否支持B5纸的双面打印? word打印出图片总是缺一部分怎么办-word打印图片不完整怎么解决_百度... 理想one哪里产的车辆? 抚州抚州ONE在哪里? one地址在哪里? 如何在图片上写字(如何在图片上添加文字) 网商贷为什么钱没到账 高级经济师职称怎么评 高级经济师需要评审吗 android 手机启动时,telephony 相关的都做了哪些事情 怎么和自己阶级不同的人交朋友? 如何与不同性格的人交往 android preload怎么用 怎么样和不同的人交朋友 安卓模拟器启动运行的具体过程是怎样的? 怎么和不同性格的人交朋友? android activitythread 怎么启动 人和人的性格都不同,那和不同性格的人该怎样做朋友? 如何与不同类型的人快速发展成朋友? Android的文件系统和分区表谁能给我详细地讲一讲 如何与观点不同的人成为朋友? 我要和不同的人做朋友,用什么等小妙招可以交到更多朋友? 和不同的人交朋友你的小窍门是什么? 怎样与自己意见不同的人交朋友? 在生活中,怎样才能和一个兴趣不同的人交朋友? 如何每天认识不同的人并且能交朋友? 如何与不同的人交朋友三年级思想品德 名片分辨率是300,不干胶分辨率是多少 谁知道PSD 做 出来名片的 尺寸 以及 分辨率。怎么办? 如何和不同年龄的人交朋友? 如何从插件apk中启动Service 和不同人的人交朋友,你有什么窍门是什么? Android开发,activity的默认启动模式为标准启动模式,什么时候会用到其他的启动模式? android下bootloader后进入recovery流程,属于安卓架构的哪一层面 android系统在启动的过程中什么时候会调用systempropertys “补偿”是什么? 赔偿和补偿有何区别?91 电力补偿补偿的是什么,怎么补偿? 补偿 是什么意思 补偿和赔偿在法律上的区别 “补偿”和“赔偿”的区别 欠补偿、过补偿和完全补偿什么意思? 补偿的途径和方式 请问现在的拆迁补偿政策是什么? 辞退员工需要怎么补偿? 抹面霜之前要抹保湿水跟乳液吗?抹面膜之前要抹保湿水跟乳液吗?保湿水 乳液 面膜 面霜的使用顺序是怎样的 想问一下 洗面奶、爽肤水、精华液、保湿凝露、面霜、乳液 的使用顺序是什么? 旅游资源对旅游活动的重要意义有哪些 立马电动车五个电瓶2400贵吗