Android学习之问题处理程序Handler
2012-05-30 15:26
393 查看
Handler是Android中的问题处理程序,它处理接收到的信息和执行传递的Runnable对象。当你在创建一个Handler对象时,系统会随之创建一个和该对象绑定在一起的一个线程信息的队列,Handler会将信息和Runnable对象传递给该队列并在它们出队列的时候执行它们。可以将Handler理解为一个消息队列,在满足条件的情况下会处理相应的消息。
1.使用Handler 发送和处理消息
下图说明了Handler的操作过程,如图所示:
下述几个方法可以向Handler传递一个Message,会调用Handler的handleMessage(Message)方法接收并处理它们,这也必须要继承Handler重写它的handleMessage(Message)方法。如果不想继承Handler,也可以实现它的一个内嵌接口Handler.Callback。
sendEmptyMessage(int),
sendMessage(Message),
sendMessageAtTime(Message,long),
sendMessageDelayed(Message,long),
Message是一个包含了一些描述和随意数据的可以发送给Handler的对象,它包含的两个整型字段arg1、arg2和obj对象,在很多时候你可以不用理会它们,不做任何分配都是可以的。What字段是用户自定义的值,用来标识Message,这个字段是最有用的字段。如果想传送有内容的Message,就可能需要使用setData(Bundle data) 方法,来通过一个Bundle对象给它设置内容。说到这里也有必要说一下Bundle ,它其实就是一个Map,包含了一些键值对。下面给出一个处理Message的Handler示例:
main.xml:
下面这段代码定义了一个名字为HandlerDemo的Activity,在其中创建了一个Handler的实例,并重写它的public void handleMessage(Message msg)方法来接收处理两种不同的Message。
Handler.java
第一种为空的不带数据的Message,只传送了一个what的值来标识Message,在public void handleMessage(Message msg)方法中处理这个Message的时候就可以通过what来识别如何去做详细处理。
第二种是带有数据的Message,Message中附带了两个字符串的值,一个是姓名,一个是电话,也给这个Message设置了一个自己的what来标识它。
以上两种Message在处理的时候都会通过Toast来展示具体的处理数据。
sendMessageAtTime(Message,long)表示处理Message的时间在给定的时间点long时,再处理这个Message。
sendMessageDelayed(Message, long)则表示接收到Message后再过long毫秒后再执行处理这个Message。
2.用Handler 处理Runnable 对象
Handler操作的对象是实现Runnable类型的对象。
● post(Runnable)——立即执行runnable的run方法
● postAtTime(Runnable,long)——在指定的时间执行runnable的run方法
● postDelayed(Runnable,long)——延迟一定的时间再执行执行runnable的run方法
上述3个方法是Handler对Runnable对象的一些处理,它们将这些对象传入到队列里,在条件满足的时候会出队列,开启线程执行它们。
这和java中的计时器Timer和计时器任务TimerTask很类似。Handler对Runnable的处理和计时器对计时器任务的处理操作方式一致。
下述代码涵盖了对于Handler传递Runnable对象的使用,只需要稍微一改动,就可以将Handler当做线程来使用。在游戏中的体现比如说不停刷新屏幕,游戏元素的动画实现等,都离不开线程的使用。
1.使用Handler 发送和处理消息
下图说明了Handler的操作过程,如图所示:
下述几个方法可以向Handler传递一个Message,会调用Handler的handleMessage(Message)方法接收并处理它们,这也必须要继承Handler重写它的handleMessage(Message)方法。如果不想继承Handler,也可以实现它的一个内嵌接口Handler.Callback。
sendEmptyMessage(int),
sendMessage(Message),
sendMessageAtTime(Message,long),
sendMessageDelayed(Message,long),
Message是一个包含了一些描述和随意数据的可以发送给Handler的对象,它包含的两个整型字段arg1、arg2和obj对象,在很多时候你可以不用理会它们,不做任何分配都是可以的。What字段是用户自定义的值,用来标识Message,这个字段是最有用的字段。如果想传送有内容的Message,就可能需要使用setData(Bundle data) 方法,来通过一个Bundle对象给它设置内容。说到这里也有必要说一下Bundle ,它其实就是一个Map,包含了一些键值对。下面给出一个处理Message的Handler示例:
main.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <Button android:text="SendEmptyMessage" android:id="@+id/send" android:layout_width="wrap_content" android:layout_ height="wrap_content"> </Button> <Button android:text="SendMessage" android:id="@+id/send2" android:layout_width="wrap_content" android:layout_ height="wrap_content"> </Button> </LinearLayout>这段代码定义了两个按钮,名字是SendEmptyMessage和SendMessage,将会通过对他们的点击处理来触发不同的发送Message的方法,给Handler发送Message。
下面这段代码定义了一个名字为HandlerDemo的Activity,在其中创建了一个Handler的实例,并重写它的public void handleMessage(Message msg)方法来接收处理两种不同的Message。
Handler.java
import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.Toast; public class HandlerDemo extends Activity { //创建了一个Handler并实现其handlerMessage方法来处理其发出的消息 Handler handler = new Handler() { @Override public void handleMessage(Message msg) { System.out.println(msg.what); //获取消息的类型what来处理消息 switch (msg.what) { case 0: Toast t1 = Toast.makeText(HandlerDemo.this, "SendEmptyMessage", Toast.LENGTH_SHORT); t1.show(); break; case 1: Bundle b = msg.getData(); Toast t2 = Toast.makeText(HandlerDemo.this, "SendMessage:" + b.get("name") + "," + b.get("tel"), Toast.LENGTH_SHORT); t2.show(); System.out.println(b.get("name")); break; } super.handleMessage(msg); } }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //初始化两个按钮,并设置其监听事件,使用这两个按钮来给Hanlder发送消息 Button send = (Button) findViewById(R.id.send); Button send2 = (Button) findViewById(R.id.send2); send.setOnClickListener(listener); send2.setOnClickListener(listener); } OnClickListener listener = new OnClickListener() { @Override public void onClick(View v) { switch (v.getId()) { case R.id.send: //使用Handler的方法发送一个空消息指令,指令的值为0 handler.sendEmptyMessage(0); break; case R.id.send2: //使用Handler发送一个Message,并在Message中附带资料 Message msg = new Message(); msg.what = 1; Bundle b = new Bundle(); b.putString("name", "peiandsky"); b.putString("tel", "136********"); msg.setData(b); if (handler.sendMessage(msg)) { System.out.println("send success"); } else { System.out.println("send fail"); } break; } } }; }首先通过findViewById找到两个Button对象,并为他们设定监听事件。在监听器OnClickListener的实例listener 中根据不同按钮的按下发送不同的Message。
第一种为空的不带数据的Message,只传送了一个what的值来标识Message,在public void handleMessage(Message msg)方法中处理这个Message的时候就可以通过what来识别如何去做详细处理。
第二种是带有数据的Message,Message中附带了两个字符串的值,一个是姓名,一个是电话,也给这个Message设置了一个自己的what来标识它。
以上两种Message在处理的时候都会通过Toast来展示具体的处理数据。
sendMessageAtTime(Message,long)表示处理Message的时间在给定的时间点long时,再处理这个Message。
sendMessageDelayed(Message, long)则表示接收到Message后再过long毫秒后再执行处理这个Message。
2.用Handler 处理Runnable 对象
Handler操作的对象是实现Runnable类型的对象。
● post(Runnable)——立即执行runnable的run方法
● postAtTime(Runnable,long)——在指定的时间执行runnable的run方法
● postDelayed(Runnable,long)——延迟一定的时间再执行执行runnable的run方法
上述3个方法是Handler对Runnable对象的一些处理,它们将这些对象传入到队列里,在条件满足的时候会出队列,开启线程执行它们。
这和java中的计时器Timer和计时器任务TimerTask很类似。Handler对Runnable的处理和计时器对计时器任务的处理操作方式一致。
下述代码涵盖了对于Handler传递Runnable对象的使用,只需要稍微一改动,就可以将Handler当做线程来使用。在游戏中的体现比如说不停刷新屏幕,游戏元素的动画实现等,都离不开线程的使用。
import android.app.Activity; import android.os.Bundle; import android.os.Handler; public class HandlerDemo2 extends Activity { //创建Handler实例 Handler handler = new Handler(); //创建3个Runnable对象的实例,分别为runnable1、runnable2和runnable3 Runnable runnable1 = new Runnable() { @Override public void run() { System.out.println("post:" + System.currentTimeMillis()); } }; Runnable runnable2 = new Runnable() { @Override public void run() { System.out.println("postDelayed:" + System.currentTimeMillis()); } }; Runnable runnable3 = new Runnable() { @Override public void run() { System.out.println("postAtTime:" + System.currentTimeMillis()); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //在程序开始运行时使用handler执行3个runnable handler.post(runnable1); handler.postDelayed(runnable2, 1000); handler.postAtTime(runnable3, 5000); } }再来对代码进行一些改动:
Handler handler = new Handler(); Runnable runnable1 = new Runnable() { @Override public void run() { //游戏逻辑,绘图不断刷新屏幕等操作 //延迟一段时间后调用自身,形成无限递归操作 handler.postDelayed(runnable1, 100); System.out.println("game thread"); } };做出改动后,你会发现game thread在每隔100毫秒后就会自动打印一次,重复执行,就可以当做线程来使用了。这也是Handler的另一个比较重要的用途。
相关文章推荐
- 【ASP.NET 问题】IIS发布网站后出现 "处理程序“PageHandlerFactory-Integrated”在其模块列表中有一个错误"的解决办法
- android——处理Google play因WebView SSL Error Handler alerts被拒的问题
- 学习笔记---httpHandler处理程序
- 【转】Android 中处理崩溃异常并重启程序出现页面重叠的问题
- 【android】Handler学习中的问题
- .net 4.0发布后不能正常显示图片问题,将iis应用程序池设置成4.0版本,报告错误:处理程序“PageHandlerFactory-Integrated”在其模块列表中有一个错误模块“ManagedPipelineHandler”
- Android编程学习之Message处理Handler
- 深入理解Android的消息处理系统---Handler、Looper、Thread学习记录
- 32.Android之消息处理系统Looper、Handler、Thread简单学习
- android 中处理崩溃异常并重启程序出现页面重叠的问题
- 【Android】Handler使用入门 处理耗时较长的程序
- android 处理程序全局异常和错误,UncaughtExceptionHandler
- application Initialization设置导致处理程序ExtensionlessUrlHandler-Integrated-4.0在其模块列表中有一个错误模块问题的解决
- 【android学习】onSaveInstanceState使用详解-之解决问题:android程序崩溃后,app异常
- application Initialization设置导致处理程序ExtensionlessUrlHandler-Integrated-4.0在其模块列表中有一个错误模块问题的解决
- Android ViewPager+Handler实现无限轮播和监听处理事件时轮播速度越来越快的问题解决
- 【ASP.NET 问题】IIS发布网站后出现 "处理程序“PageHandlerFactory-Integrated”在其模块列表中有一个错误"的解决办法
- Android学习札记28:深入理解Android中的消息处理机制——Thread、Looper、MessageQueue和Handler(2)
- android学习--手机连接到PC后程序不能检测手机的SDCard问题
- android消息处理机制学习(一)-Handler,Message,MessageQueue,Looper简介