您的位置:首页 > 移动开发 > Android开发

Android中的Handler的机制与用法详解

2016-09-02 15:54 381 查看
android的handler 是一个神奇东西,处理异步消息的时候,我们离不开他.那么他的具体的介绍是什么了?

一:Handler基本概念:

Handler主要用于异步消息的处理:当发出一个消息之后,首先进入一个消息队列,发送消息的函数即刻返回,而另外一个部分逐个的在消息队列中将消息取出,然后对消息进行出来,就是发送消息和接收消息不是同步的处理。 这种机制通常用来处理相对耗时比较长的操作。

Handler 是 Android 给我们提供来更新 UI 的一套机制,也是一套消息处理的机制,我们可以发送消息,也可以通过它来处理消息,Handler 在我们的 framework 中是非常常见的。

Android 在设计的时候,就封装了一套消息创建、传递、处理机制,如果不遵循这样的机制就没有办法更新 UI 信息,就会抛出异常信息。

二:了解几个概念

很多Android初学者对Android 中的Handler不是很明白,其实Google参考了Windows的消息处理机制,在Android系统中实现了一套类似的消息处理机制。

在下面介绍Handler机制前,首先得了解以下几个概念:

Message 消息,理解为线程间通讯的数据单元。例如后台线程在处理数据完毕后需要更新UI,则可发送一条包含更新信息的Message给UI线程。

Message Queue 消息队列,用来存放通过Handler发布的消息,按照先进先出执行。

Handler Handler是Message的主要处理者,负责将Message添加到消息队列以及对消息队列中的Message进行处理。

Looper 循环器,扮演Message Queue和Handler之间桥梁的角色,循环取出Message Queue里面的Message,并交付给相应的Handler进行处理。

线程 UI thread 通常就是main thread,而Android启动程序时会替它建立一个Message Queue。每一个线程里可含有一个Looper对象以及一个MessageQueue数据结构。在你的应用程序里,可以定义Handler的子类别来接收Looper所送出的消息。

三:Handler的用法

3.1对于handler的常用的一些方法有:

post(Runnable)

postAtTime(Runnable,long)

postDelayed(Runnable long)

sendEmptyMessage(int)

sendMessage(Message)

sendMessageAtTime(Message,long)

sendMessageDelayed(Message,long)

以上post类方法允许你排列一个Runnable对象到主线程队列中,

sendMessage类方法, 允许你安排一个带数据的Message对象到队列中,等待更新.

使用 Handler 在子线程中向 UI 线程发送一个消息进行 UI 的更新

创建一个 Message, Message msg = new Message(); msg.arg1 = 88;

handler.sendMessage(msg); msg.obj = xxx; 可以传递一个对象

当然不一定要用 new 一个 Message,也可以复用系统的 message 对象 Message msg = handler.obtainMessage();

3.2 传递 Callback 对象

Callback 用于截获 handler 发送的消息,如果返回 true 就截获成功不会向下传递了。

public Handler mHandler = new Handler(new Handler.Callback() {

@Override

public boolean handleMessage(Message msg) {

// TODO Auto-generated method stub

Toast.makeText(getApplicationContext(), “HandleMessage 1”, Toast.LENGTH_SHORT).show();

return true;

}

}) {

public void handleMessage(Message msg) {

// TODO Auto-generated method stub

Toast.makeText(getApplicationContext(), “handleMessage 1”, Toast.LENGTH_SHORT).show();

};

}

上面的示例中,第一个有返回值的 handlerMessage 方法是 Callback 的回调,如果返回true,则不执行下面的 handlerMessage 方法,从而达到拦截 handler 发送的消息的目的,如果返回 false,则会继续执行 handlerMessage 方法。

四:Handler原理

4.1 Android 为什么要设计只能通过 Handler 机制更新 UI 呢?

最根本的目的就是解决多线程并发的问题,假设在一个 Activity 当中,有多个线程去更新 UI,并且对更新的 UI 的操作进行枷锁处理的话又会产生什么样的问题呢? 那就是性能下降,Handler 通过消息队列,保证了消息处理的先后有序。

鉴于以上问题的考虑,Android 给我们提供了一套更新 UI 的机制,我们只要使用一套机制就好,所有的更新 UI 的操作都是在主线程中轮询处理。

4.2 Handler 的原理是什么?

Handler 封装了消息的发送(主要包括消息发送给谁) Looper:

内部包含一个消息队列也就是 MessageQueue,所有 Handler 发送的消息都走向这个队列。

Looper.loop()方法,就是一个 for 死循环,不断的从 MessageQueue 取消息,如果有消息就处理消息,没有消息就阻塞。

MessageQueue,就是一个消息队列,可以添加消息,处理消息。

Handler 也不难,比较简单,在构造 Handler 时候内部会跟 Looper 进行关联,通过 Looper.myLooper() 获取到 Looper,找到 Looper 也就找到了 MessageQueue。在 Handler 中发送消息,其实是向 MessageQueue 队列中发送消息。

4.3 Handler 与 Looper、MessageQueue 的关系

这一小结:handler 负责发送消息,Looper 负责接收 Handler 发送消息,并直接把消息回传给 handler 自己,MessageQueue 就是一个存储消息的容器。

下图展示了 Handler、MessageQueue、Looper 之间是如何协作的。



五:Handler 与子线程

5.1 自定义与线程相关的 Handler

class MyThread extends Thread {

public Handler handler;

@Override

public void run() {

Looper.prepare(); //new 一个Looper对象

handler = new Handler() { //拿到当前线程的 Looper 对象

@Override

public void handlerMessage(Message msg) {

// TODO Auto-generated method stub

System.out.println(“current thread:” + Thread.currentThread());

}

};

Looper.loop();//开始死循环处理消息

};

}

一般 UI 主线程中不要执行一些耗时的操作,这样就可以通过子线程消息来处理耗时操作。

5.2 HandlerThread是什么?

HandlerThread 继承于 Thread,所以它本质就是个 Thread。与普通的 Thread 的差别就在于,它有个 Looper 成员变量。这个 Looper 其实就是对消息队列以及队列处理逻辑的封装,简单来说就是消息队列+消息循环。

当我们需要一个工作线程,而不是把它当作一次性消耗品,用过即废的话,就可以使用它。

private Handler mHandler = null;

private HandlerThread mHandlerThread = null;

private void sendRunnableToWorker(Ruannable run) {

if (null == mHandlerThread) {

mHandlerThread = new HandlerThread(“WorkerThread”);

// 给工作者线程低优先级

mHandlerThread.setPriority(Thread.MIN_PRIORITY);

mHandlerThread.start();

}

if (null == mHandler) {

mHandler = new Handler(mHandlerThread.getLooper());

}

mHandler.post(run);

}

6. 主线程与子线程之间的信息交互

//创建主线程的Handler

private Handler mHandler = new Handler() {

public void handleMessage(Message msg) {

Message mssage = new Message();

System.out.println(“main Handler”);

//向子线程发送消息

threadHandler.sendMessageDelayed(message, 1000);

};

};

//创建子线程的 handler

private Handler threadHandler;

@Override

protected void onCreate(Bundle saveInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

HandlerThread thread = new HandlerThread("handlerThread");
//创建子线程的 handler
threadHandler = new Handler(thread.getLooper()) {
public void handlerMessage(Message msg) {
Message message = new Message();
//向主线程发送消息
mHandler.sendMessageDelayed(message, 1000);
};
};


}

7. Android 中更新 UI 的几种方式

Android 中更新 UI 的 4 种方式:

runOnUiThread

handler 的 post

handler 的 sendMessage

View 自身的 post

文中大部分转载自:http://it.51xw.net/mobile/1000b7.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: