事件处理:当用户在程序界面上执行各种操作时,应用程序必须为用户动作提供相应动作,这种相应动作就需要通过事件处理来完成
两种:
1.基于监听器的事件处理(优先触发)
方法:绑定特定的事件监听器setOnclickListener。还允许UI组件的android:onClick属性指定事件监听方法再在Activity中定义该事件
监听方法。
eg:android:onClick = "clickHandler"
则在Activity中定义一个clickHandler(View source)方法,该方法将会负责处理该按钮上的单击事件。
事件监听的处理模型主要涉及如下三类对象:
->Event Source(事件源):事件发生的场所,就是各个组件(按钮、窗口)
->Event :事件封装了界面组件上发生的特定事情,如果程序需要活的界面组件上所发生事件的相关信息,一般通过Event对象获得。
->Event Listener :负责监听事件源所发生的事件,并对各种事件做出相应的相应。
Android使用的是委派式(Delegation)事件处理方式:普通组件(事件源)将整个事件处理委托给特定的对象(事件监听器),当该事件
源发生指定的事件时,就通知所委托的事件处理器(事件监听器里的实例方法)来做出相应的响应。
事件编程的关键就是实现事件监听器类。如果事件发生时有较多的信息需要传给事件监听器,那么就需要将事件信息封装成Event对象,
该Event对象将作为参数传入事件处理函数。
监听器接口:OnclickListener:单击事件
OnCreateContentMenuListener:创建上下文菜单事件
OnFocusChangeListener:焦点改变事件
OnKeyListener:按键事件
OnLongClickListener:长单击事件
OnTouchListener:触摸屏事件
程序中实现事件监听器形式:
1>内部类形式:将事件监听器定义成当前类的内部类;
2>外部类形式:在某个事件监听器被多个GUI界面共享时;
3>Activity本身作为事件监听器类:让Activity本身实现监听器接口,实现事件处理方法;
4>内部匿名类:使用内部匿名类创建事件监听器对象,因为事件处理器没有复用价值。
2.基于回调的事件处理(提高程序内聚性)
与事件监听机制不同的是,当事件源发生特定事件之后,该事件还是由事件源本身负责处理。用户在GUI 组件上激发某个事件,组件
自己的特定的方法将会负责处理该事件。我们只能继承GUI类,并重写该类的事件处理方法。所谓提高内聚型,就是把事件处理方法
封装在内部,它更适合于应付那种事件处理逻辑比较固定组件。
基于回调的事件传播:基于回调是事件处理方法都有一个布尔类型返回值,用于标识该处理方法是否能完全处理该事件,是为true。
重写onTouchEvent方法可以相应触摸屏事件。
2.相应的系统设置的事件
应用程序监听系统设置的更改,对系统设置的更改做出相应。Configuration类用于描述手机设备上的配置信息(用户特定的配置项,
系统的动态设备配置)。
获取系统的Configuration对象:Configuration cfg = getResources().getConfiguration();
获取系统配置信息常见属性:P210
监听系统设置的更改:重写onConfigurationChanged响应系统设置更改。
用Activity的setRequestedOrientation(int)来修改屏幕的方向。
3.Handler消息传递机制
为什么只允许UI进程修改Activity里的UI组件?
如果有多个线程并发操作UI组件,会导致线程安全问题。
当一个程序第一次启动时,Android会启动一条主线程Main Thread,主线程主要负责处理与UI有关的组件。
Handler存在的意义?
Android只允许UI线程修改Activity的UI组件,会导致新启动的线程无法动态修改界面组件的属性值,需要借助Handler的消息传递
机制来实现。
Handler作用:把消息发送给Looper管理的MessageQueue,并负责处理Looper分给它的消息。
Looper作用:每个线程1个Looper来管理MessageQueue,会不断地从MessageQueue中取出消息,并将消息分给对应该Handler处理。
Looper创建过程有2种:1.主UI系统自己初始化了Looper对象,因此程序直接创建Handler就可以通过它发送处理消息。
2.自己启动的子线程,必须自己创建一个Looper对象,并启动,Looper.prepare()方法
和Looper.Loop()。
这里的线程只得是有handMessage的线程。数据从主线程->其他线程必须要:
Looper.prepare()
handMessage(Message msg)
Looper.loop 循环
MessageQueue作用:由Looper负责管理,FIFO方式
4.异步任务(AsyncTask)
为了解决新的线程不能更新UI的问题,Android有如下解决方案:
1.Handler实现线程之间的通讯
2.Activity.runOnUiThread(Runnable)
3.View.post(Runnable)
4.View.postDelayed(Runnable,long)
初此之外,AsyncTask更加轻量些,适合简单的异步操作,不需要借助线程和Handler即可实现。P220