安卓事件处理2

来源:互联网 发布:疯狂美工助手 编辑:程序博客网 时间:2024/04/29 11:32

除了基于监听的的事件处理模型外,安卓还提供了一种事件处理模型:基于回调的事件处理模型

为了使用回调机制类处理UI组件上发生的事件,我们需要为该组件提供对应的事件处理方法,但是Java又是静态语言,我们不能动态的为某一个对象添加方法,所以我们只能继承UI组件类,并重写该类的事件处理方法来实现,这就是基于回调的事件处理机制。

为了实现回调机制的事件处理,安卓为几乎所有的UI组件都提供了一些事件处理的回调方法,已View为例,该类中含有如下回调方法:

》boolean onKeyDown(int KeyCode,KeyEvent event)

》boolean onKeyUp(int KeyCode,KeyEvent event)

》boolean onTouchEvent(MotionEvent event)

》boolean onKeyLongPressed(int KeyCode,KeyEvent event)

》boolean onTrackballEvent(MotionEvent event)

》boolean onKeyShortcut(int KeyCode,KeyEvent event)

我们通过代码来理解基于回调的机制:

public MyButton extends Button{public MyButton(Context context,AttributeSet set){super(context,set);}@Overridepublic boolean onKeyDown(int keyCode,KeyEvent event){super.onKeyDown(keyCode,event);Log.v("youlebron","the button is clicked");return true;}}

<LinearLayoutandroid:orientation="vertical"android:layout_width="fill_parent"android:layout_height="fill_parent"><com.youlebon.event.MyButtonandroid:layout_width="fill_parent"android:layout_height="wrap_content"android:text="test"/></LinearLyaout>
首先我们定义了已继承了Button类的MyButton类,重写里面有关事件处理的回调方法,然后我们在布局界面的xml文件中使用这个MyButton类,这样当点击按钮时,

会实现事件处理。

几乎所有的基于回调的事件处理方法都有一个boolean类型的返回值,该返回值返回值用于标识该处理方法能否完全处理该事件。


除了上面两种事件处理机制外,安卓还提供了一种消息处理机制,其目的是解决安卓应用的多线程问题,由于安卓不允许Activity新启动的线程不能访问该Activit中的界面组件,这样就导致新启动的线程不能动态改变界面组件的函数属性值。这样就需要借助于Handle的消息传递机制来实现。

Handle类的主要作用有两个:
》在新启动的线程中发送信息

》在主线程中获取,处理信息

Handle类包含如下的方法用于发送与处理信息:

》void handleMessage(Message msg)

》final boolean hasMessage(int what)

》final boolean sendMessage(Message msg)

》final boolean sendMessageDelayed(Message msg,long delayMillis)


下面通过简单地C—S聊天应用例子说明Handle类的作用;

public class ClientThread implements Runnable{//该线程负责处理的Socketprivate Socket s;private Handler handler;//该线程所处理的Socket所对应的输入流BufferedReader br = null;public ClientThread(Socket s , Handler handler)throws IOException{this.s = s;this.handler = handler;br = new BufferedReader(new InputStreamReader(s.getInputStream()));}public void run(){try{String content = null;//不断读取Socket输入流中的内容。while ((content = br.readLine()) != null){// 每当读到来自服务器的数据之后,发送消息通知程序界面显示该数据Message msg = new Message();msg.what = 0x123;msg.obj = content;handler.sendMessage(msg);}}catch (Exception e){e.printStackTrace();}}}

这个类用于从服务器读取消息的内容,但是由于要新建一个线程,那么如何将读取的消息内容显示在文本框内呢?

这就需要使用Handle类了,在CLientThead中,我们定义了一个handle类,设置what变量为0x123,设置obj变量为读取的内容,然后发送消息,

接着我们编写主Activity类,在其中我们再定义一个Handle类用来接收新线程中定义的Handle类发送的消息,再将它显示在文本框中,这样就解决了新线程不能访问UI组件的问题。

public class MultiThreadClient extends Activity{// 定义界面上的两个文本框EditText input, show;// 定义界面上的一个按钮Button send;OutputStream os;Handler handler;@Overridepublic void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main);input = (EditText) findViewById(R.id.input);send = (Button) findViewById(R.id.send);show = (EditText) findViewById(R.id.show);Socket s;handler = new Handler(){@Overridepublic void handleMessage(Message msg){// 如果消息来自于子线程if (msg.what == 0x123){// 将读取的内容追加显示在文本框中show.append("\n" + msg.obj.toString());}}};try{s = new Socket("192.168.1.102", 29999);// 客户端启动ClientThread线程不断读取来自服务器的数据new Thread(new ClientThread(s, handler)).start(); // ①os = s.getOutputStream();}catch (Exception e){e.printStackTrace();}send.setOnClickListener(new OnClickListener(){@Overridepublic void onClick(View v){try{// 将用户在文本框内输入的内容写入网络os.write((input.getText().toString() + "\r\n").getBytes("utf-8"));// 清空input文本框input.setText("");}catch (Exception e){e.printStackTrace();}}});}}

所以,安卓主要的事件处理模型就是这三种了:基于监听器的事件处理模型,基于回调方式的事件处理模型,Handle消息传递模型。

原创粉丝点击