Android事件处理

事件处理机制

  • 基于监听的事件处理
    做法:为Android界面组件绑定特定的时间监听器。
  • 基于回调的事件处理
    做法:重写Android组件特定的回调方法,或重写Android的回调方法。

事件三要素

  • Event Source:事件源,事件发生的场所,通常就是各个组件
  • Event:时间,事件封装了界面组件上发生的特定事情
  • Event Listener:事件监听器,监听事件,并作出响应

实现事件监听器

  • 内部类:将事件监听器定义成当前类的内部类
  • 外部类:将事件监听器定义成一个外部类
  • Activity本身作为事件监听器类
  • 匿名内部类:最常用,原因:大部分事件监听器只是临时使用一次
  • 直接绑定到组件标签XML

Handler消息传递机制

Android:只允许UI线程修改Activity里的UI组件。但在实际开发中,尤其是涉及动画的游戏开发中,需要让新启动的线程周期性地改变界面组件的属性值,这就需要借助于Handler的消息传递机制来实现。

Handler作用

  • 在新启动的线程中发送消息
  • 在主线程中获取、处理消息

    为了让主线程能“适时”地处理新启动的线程所发送的消息,只能通过回调的方式来实现——开发者只要重写Handler类中的处理消息的方法,当新启动的线程发送消息时,消息会发送到与之关联的MessageQueue,而Handler会不断地从MessageQueue中获取并处理消息——这将导致Handler类中处理消息的方法被回调。

Handler、Loop、MessageQueue的工作原理

  • Message:Handler接收和处理的消息对象
  • Looper
    每个线程只能拥有一个Looper。它的loop方法负责读取MessageQueue中的消息,读到消息之后就把信息之后就把消息交给发送该消息的Handler进行处理。
  • MessageQueue
    消息队列,采用先进先出的方式来管理Message
  • Handler
    作用:发送消息和处理消息。程序使用Handler发送消息,被Handler发送的消息必须被送到指定的MessageQueue。也就是说,如果希望Handler正常工作,必须在当前线程中有一个MessageQueue,否则消息就没有MessageQueue进行保存了。不过,MessageQueue是由LoopER负责管理的,也就是说,如果希望Handler正常工作,必须在当前线程中有一个Looper对象。为了保证当前线程中有Looper对象,可分为如下两种情况处理:
    1. 主UI线程中,系统已经初始化了一个LoopER对象,因此程序直接创建Handler即可,然后就可通过Handler来发送消息,处理消息。
    2. 自己启动的子线程,必须自己创建一个Looper对象,并启动它。创建Looper对象调用它的prepare()方法即可。
尽量避免在UI线程中执行耗时的操作,通常采用启用新的线程来执行耗时任务,否则极大可能会导致ANR异常。

Async Task 异步任务

Android的UI组件主要负责处理用户的按键事件、触屏事件、屏幕绘图事件等,因此开发者的其他操作不应该、也不能阻塞UI线程,否则UI界面将会变得停止响应,超过20S将会引发Application Not Responding (ANR),必须牢记:不要在UI线程中执行一些耗时的任务。
为了解决新线程不能根性UI组件的问题,Android提供的解决方案:
1. 使用Handler实现线程之间的通信
2. Activity.runOnUiThread(Runnable)
3. View.post(Runnable)
4. View.postDelayed(Runnable, long)
以上方案出Handler外都略显繁琐。AsyncTask是一个轻量级的解决方案,适合用于简单的异步处理,不需要借助线程和Handler即可实现。

Steps

  • 创建AsyncTask子类
  • 实现如下方法
    1. doInBackground: 后台线程将要完成的任务;该方法可以调用publishProgress方法更新任务的执行进度;
    2. onProgressUpdate:在doInBackground方法中调用publishProgress更新任务的执行进度后,将会被触发;
    3. onPreExcute:在执行后台耗时操作前被调用。通常用于完成一些初始化的准备工作,比如在界面上显示进度条等;
    4. onPostExcute:当doInBackground完成后,系统自动调用该方法,并将doInBackground方法的返回值传给该方法。
  • 调用AsyncTask子类实例的execute方法执行耗时任务

使用时必须遵守的规则

  • 必须在UI线程中创建AsyncTask的实例
  • 必须在UI线程中调用AsyncTask的execute方法
  • AsyncTask的onPreExcute, onPostExcute, doInBackground, onProgressUpdate方法,不应爱由程序员调用,而由Android系统负责调用
  • 每个AsyncTask只能被执行一次,多次调用将会引发异常
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值