展会信息港展会大全

android开发之message讲解
来源:互联网   发布日期:2016-01-13 21:51:47   浏览:2405次  

导读:MessageQueue:消息队列,使用FIFO规则执行,每一个线程只可以拥有一个MessageQueue,在创建Looper对象会创建一个MessageQueue用来容纳Message队列的,其中的Message是由Looper来分发的,Message不能直接添加到Mes......

MessageQueue:消息队列,使用FIFO规则执行,每一个线程只可以拥有一个MessageQueue,在创建Looper对象会创建一个

MessageQueue用来容纳Message队列的,其中的Message是由Looper来分发的,Message不能直接添加到MessageQueue中,而是要通过与Looper关联的Handler去添加。

创建一个线程的时候,并不会自动创建其MessageQueue。通常使用一个Looper对象对该线程的MessageQueue进行管理。主线程创建时,会创建一 个默认的Looper对象,而Looper对象的创建,将自动创建一个Message Queue。其他非主线程,不会自动创建Looper,要需要的时候,通过调 用prepare函数来实现。

Message消息对象:MessageQueue中存放的对象,一个MEssageQueue中可以包含多个MEssage,可以通过 Message.obtain()或者Handle.obtainMessage()获取Message对象,但是这并不一定是直接创建一个新的实例,而 是先从消息池中看有没有可用的Message实例,存在则直接取出返回这个实例,如果消息池中没有可用的MEssage实例i,则采用给定的参数创建一个 Message对象,调用removeMessage()时,将Message从MessageQueue中删除,同时放入到消息池中。

Message 是线程之间传递信息的载体,包含了对消息的描述和任意的数据对象。Message中包含了两个额外的 int字段和一个object字段,这样在大部分情况下,使用者就不需要再做内存分配工作了。虽然Message的构造函数是public的,但是最好是 使用Message.obtain( )或Handler.obtainMessage( )函数来获取Message对象,因为Message的实现中包含了回收再利用的机制,可以提供效率。

B、创建消息

1

public final Message obtainMessage()

2

3

public final Message obtainMessage(int what)

4

5

public final Message obtainMessage(int what, Object obj)

6

7

public final Message obtainMessage(int what, int arg1, int arg2)

8

9

public final Message obtainMessage(int what, int arg1, int arg2, Object obj)

obtainmessage()是从消息池中拿来一个msg 不需要另开辟空间new

new需要重新申请,效率低,obtianmessage可以循环利用;

//use Handler.obtainMessage(),instead of msg = new Message();

//because if there is already an Message object,that not be used by

//any one ,the system will hand use that object,so you don't have to

//create and object and allocate memory.

//itis also another example of object recycling and reusing in android.

Message msg = mHandler.obtainMessage();

msg.what = UPDATE_LISTVIEW;

msg.obj = current + "/" + total + "songs";

//this method is called from worker Thread,so we cannot update UI from here.

msg.sendToTarget();

在看下面代码:

Message msg = handler.obtainMessage();

msg.arg1 = i;

msg.sendToTarget();

Message msg=new Message();

msg.arg1=i;

handler.sendMessage(msg);

第一种写法是message 从handler 类获取,从而可以直接向该handler 对象发送消息,第二种写法是直接调用 handler 的发送消息方法发送消息。

C、删除消息

删除在消息队列中未处理的消息

1

public final void removeMessages(int what)

2

3

public final void removeMessages(int what, Object object)

D、发送消息

1

public final boolean sendMessage(Message msg)

2

3

public final boolean sendMessageDelayed(Message msg, long delayMillis)

4

5

public final boolean post(Runnable r)

6

7

public final boolean postDelayed(Runnable r, long delayMillis)

3、Looper

frameworks\base\core\java\android\Os\Looper.java

Looper是线程用来运行消息循环的。线程本身是没有消息循环的,需要在线程中调用perpare函数,然后调用loop去处理消息。在Android中,系统在启动主线程的时候会自动为之建立一个Looper。

Android中的Looper类,是用来封装消息循环和消息队列的一个类,用于在android线程中进行消息处理。handler其实可以看做是一个工具类,用来向消息队列中插入消息的。

建立本线程的Looper:

public static final void prepare()

运行本线程的Looper:

public static final void loop()

注意:写在Looper.loop()之后的代码不会被执行,这个函数内部应该是一个循环,当调用mHandler.getLooper().quit()后,loop才会中止,其后的代码才能得以运行。

获取本线程的Looper:

public static final Looper myLooper()

类似的 Looper.getMainLooper() 用于获取主线程的Looper对象。

获取主线程的Looper:

public synchronized static final Looper getMainLooper()

4、Handler

frameworks\base\core\java\android\Os\Handler.java

Handler是用来发送和处理与线程相关联的Message和Runnable对象的。每个Handler都与一个单独的线程以及线程消息队列相 关联的。当你创建Handler时,Handler就与线程以及线程消息队列绑定了,从那以后,Handler就可以将 Message和Runnable发送给对应的消息队列,并且能够处理从消息队列中出来的消息。

通常是通过Handler对象来与Looper进行交互的。Handler可看做是Looper的一个接口,用来向指定的Looper发送消息及定义处理方法。

默认情况下Handler会与其被定义时所在线程的Looper绑定,比如,Handler在主线程中定义,那么它是与主线程的Looper绑定。

mainHandler = new Handler() 等价于new Handler(Looper.myLooper()).(这里Looper.myLooper()获取本线程的Looper:类似的 Looper.getMainLooper() 用于获取主线程的Looper对象。)

在非主线程中直接new Handler() 会报如下的错误:

E/AndroidRuntime( 6173): Uncaught handler: thread Thread-8 exiting due to uncaught exception

E/AndroidRuntime( 6173): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()

原因是非主线程中默认没有创建Looper对象,需要先调用Looper.prepare()启用Looper。

A、创建Handler:

创建与本地线程相关联的Handler:

1

public Handler()

2

3

public Handler(Callback callback)

创建与指定线程相关联的Handler:

1

public Handler(Looper looper)

2

3

public Handler(Looper looper, Callback callback)

E、处理消息

在Looper的loop函数中循环取出MessageQueue的接收消息队列中的消息,然后调用Hander的dispatchMessage函数对消息进行处理,至于如何处理(相应消息)则由用户指 定(三个方法,优先级从高到低:Message里面的Callback,一个实现了Runnable接口的对象,其中run函数做处理工 作;Handler里面的mCallback指向的一个实现了Callback接口的对象,里面的handleMessage进行处理;处理消息 Handler对象对应的类继承并实现了其中handleMessage函数,通过这个实现的handleMessage函数处理消息)。

(5) 基于以上知识,可实现主线程给子线程(非主线程)发送消息。

把下面例子中的mHandler声明成类成员,在主线程通过mHandler发送消息即可。

Android官方文档中Looper的介绍:

Class used to run a message loop for a thread. Threads by default do not have a message loop associated with them; to create one, call prepare() in the thread that is to run the loop, and then loop() to have it process messages until the loop is stopped.

Most interaction with a message loop is through the Handler class.

This is a typical example of the implementation of a Looper thread, using the separation of prepare() and loop() to create an initial Handler to communicate with the Looper.

01

class LooperThread extends Thread {

02

public Handler mHandler;

03

04

public void run() {

05

Looper.prepare();

06

07

mHandler = new Handler() {

08

public void handleMessage(Message msg) {

09

// process incoming messages here

10

}

11

};

12

13

Looper.loop();

14

}

15

}

赞助本站

人工智能实验室

相关热词: message

AiLab云推荐
推荐内容
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港