安卓事件处理2

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

为了使用回调机制类处理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);
}
@Override
public boolean onKeyDown(int keyCode,KeyEvent event){
super.onKeyDown(keyCode,event);
Log.v("youlebron","the button is clicked");
return true;
}
}

<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.youlebon.event.MyButton
android: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
{
	//该线程负责处理的Socket
	private 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;

	@Override
	public 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()
		{
			@Override
			public 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()
		{
			@Override
			public void onClick(View v)
			{
				try
				{
					// 将用户在文本框内输入的内容写入网络
					os.write((input.getText().toString() + "\r\n")
						.getBytes("utf-8"));
					// 清空input文本框
					input.setText("");
				}
				catch (Exception e)
				{
					e.printStackTrace();
				}
			}
		});
	}
}

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值