Android事件处理机制

  一、概述  

  不管是桌面应用还是手机应用,面对的都是用户,经常需要处理用户的操作,为用户的动作提供响应,这种机制就是事件处理

   Androd系统提供了两种事件处理机制

     a、基于监听的事件处理

     b、基于回调的事件处理

二、基于监听的事件处理

    a、涉及三个模型

         Event Source(事件源,事件发生的场所,通俗地讲就是各个组件,如按钮,菜单)(比如企业发生了火灾

         Event(事件),封装了界面上特定的事情(报警,企业处理不了,要消防局来处理)

         EventListener(事件监听器)对事件做出的响应(消防机关的警察来灭火)

 

       例子:模拟飞机的移动

public class PlaneView extends View{


public float cx;
public float cy;
Bitmap palne;
public PlaneView(Context context){
super(context);
plane=BitmapFactory.decodeResource(context.getResources(),R.drawable.iclon);
setFocusable(true);
}

//还有两个参数,三个参数的构造方法,在使用xml自定义的控件时,会默认调用第二个构造函数
//在这里省略掉了
public void onDraw(Canvas canvas){
super.onDraw(canvas);
Paint p=new Paint();
canvas.drawBitmap(plane,cx,cy,p);
}

 

    主Activity

public class PlaneGame extends Activity{
private int speed=10;//飞机的移动速度
public void onCreate(Bundle savedInstanceState){
super.onCreate();
//去标题
//全屏显示
final PlaneView planeView=new PlaneView(this);
//根据屏幕的宽高设定飞机的初始位置
planeView.cx=....;
planeView.cy=....;
planeView.setOnKeyListener(

      new onKeyListener(){
         public boolean onKey(View source,int keyCode,KeyEvent event){
          //
           //根据event.getKeyCode()来分别控制上下左右
(调整成员变量cx,cy达到改变飞机的位置)       return true;//planeView已经把把键盘触摸的事件消费了,下面的Activity一边待着去吧

}
}
}

);
}
}

 

   三、基于回调的事件处理

定义:相比于监听,回调的事件源和事件监听器统一了,也就是所组件自己就具备处理事件的能力

 

public class PlaneView extends View{


public float cx;
public float cy;
Bitmap palne;
public PlaneView(Context context){
super(context);
plane=BitmapFactory.decodeResource(context.getResources(),R.drawable.iclon);
setFocusable(true);
}

//还有两个参数,三个参数的构造方法,在使用xml自定义的控件时,会默认调用第二个构造函数
//在这里省略掉了
public void onDraw(Canvas canvas){
super.onDraw(canvas);
Paint p=new Paint();
canvas.drawBitmap(plane,cx,cy,p);
}

//增加的代码,重写按键点击的响应
public boolean onKeyDown(int keyCode,KeyEvent event){
      super.onKeyDown()keyCode,event;
syso("the onkeydown on planeView");
reutrn false;//
}
}

上面在planeview本身就完成了onkeydown的响应

 

事件响应顺序:当组件上的事件被触发后,Android系统最先触发的是按键上绑定的事件监听器,接着才触发该组件提供事件的回调方法,然后传播给该组件的Activity,如果任何一个组件处理返回了true,事件就不会继续向外传播了。

 

比较者:基于回调的事件处理具备有更加好的内聚性,模块化更加强一点,把属于一个组件的事务封装到一起

 

在handler里也有回调,因此我们把handler补充进来,形成知识连

四、handler消息传递机制

背景:由于手机的性能是有限的,为了Android性能的优化,(效率高一点),Android的UI操作不是线程安全的(线程安全就是同一个时刻只有一个线程操作数据),这就意味着当多个线程共同操作ui控件的时候可能会线程不安全,于是Android规定:只有UI主线程有权利操作UI组件。

 

为了实现这样的效果:由于新开辟的线程希望修改属性的值,却没有资格,这个尴尬的局面。Android提供了handler来完成对把控件的值修改的任务(回调的方式处理这个事件)

 

具体的过程就是:开发者只需要重写handler类的消息处理方法,当新启动线程的消息通过handler会加入的消息队列里,handler源源不断地获取这个消息队列里的消息并且一一处理,于是handler就回调了

 

 

介绍了handler 和消息队列,还差一个Looper,它就是消息队列的管理者

handler想源源不断地获取队列的message,就需要当前线程(一般是UI线程)有一个Looper对象

奇怪啊,我们主线程编写是好像没看到过Looper,为什么handler还能正常地运行呢?(因为UI线程已经初始化了Looper对象)。

如果当前线程不是UI线程,而是自己搞的一个子线程,开发者需要创建Looper对象,并且调用prepare()方法,这样handler就能正常地工作了(因为Looper已经管理了消息队列)

 

对Looper源代码的研究

private Looper(){
    mQueue=new MessageQueue();
mRun=tru;
mThread=Thread,.currentThread();
}

//说明Looper不能通过构造函数实例化,Looper在初始化时会指明哪个消息队列,哪个线程

 

public static final void prepare(){
if(sThreadlocal.get()!=null){
  throw new Exception(一个线程里只能创建一个Looper);
}
sThreadlocal.set(new looper());
}

 threadlocal线程范围内数据共享,类似map集合,键值对,

 

例子:明天补充

 

 

今天复习了两种事件,自定义控件,多线程,handler,挺不错啊,加油

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值