================================================================
文章来源:http://blog.csdn.net/tianxiangshan/article/details/8448441
=================================================================
Handler是Android消息模型最重要的一个概念,它可以说是Android消息模型的核心,对于Looper、MessageQueue、Message 等概念一般在应用中很少使用。在Android系统框架中也频繁地使用Handler,而且为了更方便地使用Handler,还把Handler进行了一些列的封装,下面就通过列举一些Handler的使用方法。
1)Acitivity的runOnUiThread方法
使用Acitivity的runOnUiThread方法执行代码时,可以保证所有的代码都在UI线程中执行,使用方法如下:
1 | activity.runOnUiThread( new Runnable() { |
2 | @Override |
3 | public void run() { |
4 | textView.setText( "HelloWorld" ); |
5 | //所有的代码都会在UI线程中执行 |
6 | } |
7 | }); |
2)View的post和postDelay方法
View的post方法与Acitivity的runOnUiThread方法类似,可以保证所有的代码都在UI线程中执行,View的post方法使用方法如下:
1 | view.post(( new Runnable() { |
2 | @Override |
3 | public void run() { |
4 | textView.setText( "HelloWorld" ); |
5 | //所有的代码都会在UI线程中执行 |
6 | } |
7 | }); |
View的postDelay方法与post方法能保证所有的代码都在UI线程中执行,并且还可以让代码延迟一定的时间后执行,View的postDelay方法使用方法如下:
1 | view. postDelay (( new Runnable() { |
2 | @Override |
3 | public void run() { |
4 | textView.setText( "HelloWorld" ); |
5 | //所有的代码都会在UI线程中执行 |
6 | } |
7 | }, 1000 ); // 延迟1秒执行 |
3)AsyncTask
AsyncTask是对Android线程模型的一种高度封装,而且使用java的泛型技术,使用非常方便,而且能够解决通用问题。在使用AsyncTask类时,需要扩展它并实现以下几个方法:
public void onPreExecute() 在UI线程中执行,进行以下初始化操作
public Result doInBackground(Params... params) 在后台线程中执行
public void onProgressUpdate(Progress... values) 在UI线程中执行,通知UI线程更新界面
public void onPostExecute(Result result) 任务结束后,在UI线程中执行
public void onCancelled () 任务取消时,在UI线程中执行
AsyncTask 使用了Java的泛型技术,所以在使用时需要使用具体的类型,一般的使用方法代码如下:
01 | public class UserTask extends AsyncTask < String, Void, Void > { |
02 | @Override |
03 | public void onPreExecute() { |
04 | //初始化操作,在主线程中执行 |
05 | } |
06 | @Override |
07 | public Result doInBackground(String... params) { |
08 | //在后台线程中执行任务 |
09 | } |
10 | @Override |
11 | public void onCancelled() { |
12 | //取消任务时的回调 |
13 | } |
14 | @Override |
15 | public void onPostExecute() { |
16 | //任务执行结束时的回调,在主线程中执行 |
17 | } |
18 | } |
在代码中使用UserTask时,必须要在UI线程中执行execute方法,代码如下:
1 | new UserTask ().execute( new String [] {“”}); |
4) IdlerHandler
使用IdlerHandler可以向当前线程的消息队列里发送操作,这些操作之后在空闲的时候才会执行,它们的优先级非常低。需要注意的是queueIdle的方法可以返回一个布尔值,如果返回false,说明IdleHandler执行一次之后就会被删除,如果返回true,说明IdleHandler一直是有效的,只要系统处于空闲状态就执行IdleHandler的queueIdle方法。使用方式如下:
1 | Looper.myQueue().addIdleHandler( new IdleHandler() { |
2 | @Override |
3 | public boolean queueIdle() { |
4 | //系统空闲时进行资源回收操作 |
5 | return false ; |
6 | } |
7 | }); |
5) Handler
Handler是Android消息模型最重要的一个组件,使用它可以在线程之间相互发送消息,实现线程之间的通信。处理使用Handler发送消息以外,通常需要继承Handler类,并重写handleMessage(Message msg) 方法, 接收消息并处理消息。
下面通过一个实例来说明Handler的使用方法。例子的主要功能是:通过线程修改界面Button的内容,完整的代码如下:
01 | public class MyHandlerActivity extends Activity { |
02 |
03 | Button button; |
04 | MyHandler myHandler; |
05 |
06 | protected void onCreate(Bundle savedInstanceState) { |
07 | super .onCreate(savedInstanceState); |
08 | setContentView(R.layout.handlertest); |
09 | button = (Button) findViewById(R.id.button); |
10 | myHandler = new MyHandler(); |
11 | // 当创建一个新的Handler实例时, 它会绑定到当前线程和消息的队列中,开始分发数据 |
12 | // Handler有两个作用, |
13 | //(1) : 定时执行Message和Runnalbe 对象 |
14 | // (2): 让一个动作,在不同的线程中执行. |
15 | // 它安排消息,用以下方法 |
16 | // post(Runnable) |
17 | // postAtTime(Runnable,long) |
18 | // postDelayed(Runnable,long) |
19 | // sendEmptyMessage(int) |
20 | // sendMessage(Message); |
21 | // sendMessageAtTime(Message,long) |
22 | // sendMessageDelayed(Message,long) |
23 | // 以上方法以 post开头的可以处理Runnable对象 |
24 | //sendMessage()可以处理Message对象(Message里可以包含数据,) |
25 | MyThread m = new MyThread(); |
26 | new Thread(m).start(); |
27 | } |
28 |
29 | /** |
30 | * 接受消息,处理消息 ,此Handler会与当前主线程一块运行 |
31 | * */ |
32 | class MyHandler extends Handler { |
33 | |
34 | //默认构造函数 |
35 | public MyHandler() { |
36 | super (); |
37 | } |
38 | |
39 | // 带有Looper参数的构造函数 |
40 | public MyHandler(Looper L) { |
41 | super (L); |
42 | } |
43 | // 子类必须重写此方法,处理消息 |
44 | @Override |
45 | public void handleMessage(Message msg) { |
46 | Log.d( "MyHandler" , "handleMessage......" ); |
47 | super .handleMessage(msg); |
48 | // 此处可以更新UI |
49 | Bundle b = msg.getData(); |
50 | String color = b.getString( "color" ); |
51 | String btn = msg.obj.toString(); |
52 | MyHandlerActivity. this .button.append(color + btn); |
53 | } |
54 | } |
55 |
56 | class MyThread implements Runnable { |
57 | public void run() { |
58 | try { |
59 | Thread.sleep( 2000 ); |
60 | } catch (InterruptedException e) { |
61 | // TODO Auto-generated catch block |
62 | e.printStackTrace(); |
63 | } |
64 | Log.d( "thread......." , "mThread........" ); |
65 | // 使用Message能够传递多种数据具体可以参考Message的源码 |
66 | // 最常用的可以使用Message的obj对象在线程之间传递对象数据 |
67 | Message msg = new Message(); |
68 | Bundle b = new Bundle(); // 存放数据 |
69 | b.putString( "color" , "Red" ); |
70 | msg.setData(b); |
71 | msg.obj = new String(“Button”); |
72 | MyHandlerActivity. this .myHandler.sendMessage(msg); // 向Handler发送消息,更新UI |
73 | } |
74 | } |
75 | } |
HandlerThread是一个带有消息循环的线程,并且有自己的消息队列,能够接受其他线程发送消息。使用方法Java代码如下:
01 | HandlerThread tt = new HandlerThread( "handlerThread" ); |
02 | tt.start(); //启动线程 |
03 | Handler handler = new Handler(tt.getLooper()); |
04 | handler.postDelayed( new Runnable() { |
05 |
06 | @Override |
07 | public void run() { |
08 | System.out.println( "ThreadName:" + Thread.currentThread().getName()); |
09 | ((HandlerThread)Thread.currentThread()).getLooper().quit(); //关闭消息循环,退出线程 |
10 | } |
11 |
12 | }, 1000 ); |
=================================================================================================================
个人总结:
public final boolean postDelayed(Runnable r, long delayMillis)
从当前时间开始延迟delayMillis时间后执行Runnable,只执行一次
public final boolean postAtTime(Runnable r,long uptimeMillis)
在指定的有效时间内执行并且完成Runnable